summaryrefslogtreecommitdiff
path: root/Utility/NotificationBroadcaster.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2013-03-27 14:56:15 -0400
committerGravatar Joey Hess <joey@kitenet.net>2013-03-27 14:56:20 -0400
commitb9468c73eba89e706dde800eb43a48d682f09b5a (patch)
tree529c1d87944b4fbf867c512722f0a736b46512b1 /Utility/NotificationBroadcaster.hs
parentc96dea4df695fb7516ea801ab7909da4bea29bcc (diff)
webapp: Fix a race that sometimes caused alerts or other notifications to be missed if they occurred while a page was loading.
When a page is loaded, the javascript requests an notification url, and does long polling on the url to be informed of changes. But if a change occured before the notification url was requested, it would not be notified of that change, and so the page display would not update. I fixed this by *always* updating the page display after it gets the notification url. This is extra work, but the overhead is not noticable in the other overhead of loading a page. (A nicer way would be to somehow record the version of a page initially loaded, and then compare it with the current version when getting the notification url, and only force an update if it's changed. But getting the "version" of the different parts of the page that use long polling is difficult.)
Diffstat (limited to 'Utility/NotificationBroadcaster.hs')
-rw-r--r--Utility/NotificationBroadcaster.hs17
1 files changed, 13 insertions, 4 deletions
diff --git a/Utility/NotificationBroadcaster.hs b/Utility/NotificationBroadcaster.hs
index 413ec2d75..b873df655 100644
--- a/Utility/NotificationBroadcaster.hs
+++ b/Utility/NotificationBroadcaster.hs
@@ -40,14 +40,23 @@ data NotificationHandle = NotificationHandle NotificationBroadcaster Notificatio
newNotificationBroadcaster :: IO NotificationBroadcaster
newNotificationBroadcaster = atomically $ newTMVar []
-{- Allocates a notification handle for a client to use. -}
-newNotificationHandle :: NotificationBroadcaster -> IO NotificationHandle
-newNotificationHandle b = NotificationHandle
+{- Allocates a notification handle for a client to use.
+ -
+ - An immediate notification can be forced the first time waitNotification
+ - is called on the handle. This is useful in cases where a notification
+ - may be sent while the new handle is being constructed. Normally,
+ - such a notification would be missed. Forcing causes extra work,
+ - but ensures such notifications get seen.
+ -}
+newNotificationHandle :: Bool -> NotificationBroadcaster -> IO NotificationHandle
+newNotificationHandle force b = NotificationHandle
<$> pure b
<*> addclient
where
addclient = do
- s <- newEmptySV
+ s <- if force
+ then newSV ()
+ else newEmptySV
atomically $ do
l <- takeTMVar b
putTMVar b $ l ++ [s]