@@ -34,23 +34,50 @@ newAsyncDebouncer = Debouncer . asyncRegisterEvent <$> STM.newIO
3434
3535-- | Register an event that will fire after the given delay if no other event
3636-- for the same key gets registered until then.
37- asyncRegisterEvent :: (Eq k , Hashable k ) => STM. Map k (TVar (Seconds , IO () )) -> Seconds -> k -> IO () -> IO ()
37+ asyncRegisterEvent
38+ :: (Eq k , Hashable k )
39+ => STM. Map k (TVar (Maybe (Seconds , IO () )))
40+ -> Seconds
41+ -> k
42+ -> IO ()
43+ -> IO ()
3844asyncRegisterEvent d delay k fire = join $ atomicallyNamed " debouncer - register" $ do
45+ -- The previous TVar for this key, if any
3946 prev <- STM. lookup k d
4047 case prev of
41- Just v -> writeTVar v (delay, fire) >> return (pure () )
48+ Just v -> do
49+ current <- readTVar v
50+ case current of
51+ -- Not empty, means that there is a thread running the actions
52+ Just _ -> writeTVar v (Just (delay, fire)) >> return (pure () )
53+ -- Empty = no thread. We need to start one for running the action
54+ Nothing -> writeTVar v (Just (delay, fire)) >> return (restart v)
55+
56+ -- No previous TVar, we need to insert one and restart a thread for running the action
4257 Nothing
4358 | delay == 0 -> return fire
4459 | otherwise -> do
45- var <- newTVar (delay, fire)
60+ var <- newTVar (Just ( delay, fire) )
4661 STM. insert var k d
47- return $ void $ async $
62+ return (restart var)
63+ where
64+ -- | Restart a thread to run the action stored in the given TVar
65+ -- Once the action is done, the thread dies.
66+ -- Assumes the Tvar is not empty
67+ restart var =
68+ void $ async $
4869 join $ atomicallyNamed " debouncer - sleep" $ do
49- (s,act) <- readTVar var
50- unsafeIOToSTM $ sleep s
51- return $ do
52- atomically (STM. delete k d)
53- act
70+ contents <- readTVar var
71+ case contents of
72+ Nothing -> error " impossible"
73+ Just (s,act) -> do
74+ -- sleep for the given delay
75+ -- If the TVar is written while sleeping,
76+ -- the transaction will restart
77+ unsafeIOToSTM $ sleep s
78+ -- we are done - empty the TVar before exiting
79+ writeTVar var Nothing
80+ return act
5481
5582-- | Debouncer used in the DAML CLI compiler that emits events immediately.
5683noopDebouncer :: Debouncer k
0 commit comments