-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Servantify /teams/notifications (#3020)
Co-authored-by: Leif Battermann <[email protected]> Co-authored-by: Leif Battermann <[email protected]>
- Loading branch information
1 parent
8051138
commit e8d5492
Showing
12 changed files
with
160 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Migrate `/teams/notifications` to use the Servant library. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
libs/wire-api/src/Wire/API/Routes/Public/Galley/TeamNotification.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
module Wire.API.Routes.Public.Galley.TeamNotification where | ||
|
||
import Data.Range | ||
import Imports | ||
import Servant | ||
import Wire.API.Error | ||
import Wire.API.Error.Galley | ||
import Wire.API.Notification | ||
import Wire.API.Routes.Named | ||
import Wire.API.Routes.Public | ||
|
||
type TeamNotificationAPI = | ||
Named | ||
"get-team-notifications" | ||
( Summary "Read recently added team members from team queue" | ||
:> Description GetTeamNotificationsDescription | ||
:> "teams" | ||
:> "notifications" | ||
:> ZUser | ||
:> CanThrow 'TeamNotFound | ||
:> CanThrow 'InvalidTeamNotificationId | ||
:> QueryParam' | ||
[ Optional, | ||
Strict, | ||
Description "Notification id to start with in the response (UUIDv1)" | ||
] | ||
"since" | ||
NotificationId | ||
:> QueryParam' | ||
[ Optional, | ||
Strict, | ||
Description "Maximum number of events to return (1..10000; default: 1000)" | ||
] | ||
"size" | ||
(Range 1 10000 Int32) | ||
:> Get '[Servant.JSON] QueuedNotificationList | ||
) | ||
|
||
type GetTeamNotificationsDescription = | ||
"This is a work-around for scalability issues with gundeck user event fan-out. \ | ||
\It does not track all team-wide events, but only `member-join`.\ | ||
\\n\ | ||
\Note that `/teams/notifications` behaves differently from `/notifications`:\ | ||
\\n\ | ||
\- If there is a gap between the notification id requested with `since` and the \ | ||
\available data, team queues respond with 200 and the data that could be found. \ | ||
\They do NOT respond with status 404, but valid data in the body.\ | ||
\\n\ | ||
\- The notification with the id given via `since` is included in the \ | ||
\response if it exists. You should remove this and only use it to decide whether \ | ||
\there was a gap between your last request and this one.\ | ||
\\n\ | ||
\- If the notification id does *not* exist, you get the more recent events from the queue \ | ||
\(instead of all of them). This can be done because a notification id is a UUIDv1, which \ | ||
\is essentially a time stamp.\ | ||
\\n\ | ||
\- There is no corresponding `/last` end-point to get only the most recent event. \ | ||
\That end-point was only useful to avoid having to pull the entire queue. In team \ | ||
\queues, if you have never requested the queue before and \ | ||
\have no prior notification id, just pull with timestamp 'now'." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
module Galley.API.Public.TeamNotification where | ||
|
||
import Data.Id | ||
import Data.Range | ||
import qualified Data.UUID.Util as UUID | ||
import qualified Galley.API.Teams.Notifications as APITeamQueue | ||
import Galley.App | ||
import Galley.Effects | ||
import Imports | ||
import Polysemy | ||
import Wire.API.Error | ||
import Wire.API.Error.Galley | ||
import Wire.API.Internal.Notification | ||
import Wire.API.Routes.API | ||
import Wire.API.Routes.Public.Galley.TeamNotification | ||
|
||
teamNotificationAPI :: API TeamNotificationAPI GalleyEffects | ||
teamNotificationAPI = | ||
mkNamedAPI @"get-team-notifications" getTeamNotifications | ||
|
||
type SizeRange = Range 1 10000 Int32 | ||
|
||
-- | See also: 'Gundeck.API.Public.paginateH', but the semantics of this end-point is slightly | ||
-- less warped. This is a work-around because we cannot send events to all of a large team. | ||
-- See haddocks of module "Galley.API.TeamNotifications" for details. | ||
getTeamNotifications :: | ||
Members | ||
'[ BrigAccess, | ||
ErrorS 'TeamNotFound, | ||
ErrorS 'InvalidTeamNotificationId, | ||
TeamNotificationStore | ||
] | ||
r => | ||
UserId -> | ||
Maybe NotificationId -> | ||
Maybe SizeRange -> | ||
Sem r QueuedNotificationList | ||
getTeamNotifications uid since size = do | ||
since' <- checkSince since | ||
APITeamQueue.getTeamNotifications | ||
uid | ||
since' | ||
(fromMaybe defaultSize size) | ||
where | ||
checkSince :: | ||
Member (ErrorS 'InvalidTeamNotificationId) r => | ||
Maybe NotificationId -> | ||
Sem r (Maybe NotificationId) | ||
checkSince Nothing = pure Nothing | ||
checkSince (Just nid) | ||
| (UUID.version . toUUID) nid == 1 = | ||
(pure . Just) nid | ||
checkSince (Just _) = throwS @'InvalidTeamNotificationId | ||
|
||
defaultSize :: SizeRange | ||
defaultSize = unsafeRange 1000 |
Oops, something went wrong.