From 5be562b9acbce1a02b86cc52b4575b6d20d9c3ea Mon Sep 17 00:00:00 2001
From: Jens Nolte <git@queezle.net>
Date: Sun, 12 Sep 2021 02:06:45 +0200
Subject: [PATCH] Remove awaitable from observe callback

Co-authored-by: Jan Beinke <git@janbeinke.com>
---
 src/Quasar/Observable.hs | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/src/Quasar/Observable.hs b/src/Quasar/Observable.hs
index 6c1948c..4aac428 100644
--- a/src/Quasar/Observable.hs
+++ b/src/Quasar/Observable.hs
@@ -91,12 +91,12 @@ class IsRetrievable v o => IsObservable v o | o -> v where
   observe
     :: MonadResourceManager m
     => o -- ^ observable
-    -> (forall f. MonadResourceManager f => ObservableMessage v -> f (Awaitable ())) -- ^ callback
+    -> (forall f. MonadResourceManager f => ObservableMessage v -> f ()) -- ^ callback
     -> m ()
   -- NOTE Compatability implementation, has to be removed when `oldObserve` is removed
   observe observable callback = mask_ do
     resourceManager <- askResourceManager
-    disposable <- liftIO $ oldObserve observable (\msg -> runReaderT (await =<< callback msg) resourceManager)
+    disposable <- liftIO $ oldObserve observable (\msg -> runReaderT (callback msg) resourceManager)
     registerDisposable disposable
 
   -- | Old signature of `observe`, will be removed from the class once it's no longer used for implementations.
@@ -104,7 +104,7 @@ class IsRetrievable v o => IsObservable v o | o -> v where
   oldObserve observable callback = do
     resourceManager <- unsafeNewResourceManager
     onResourceManager resourceManager do
-      observe observable $ \msg -> liftIO (callback msg) >> pure (pure ())
+      observe observable $ \msg -> liftIO (callback msg)
     pure $ toDisposable resourceManager
 
   toObservable :: o -> Observable v
@@ -126,21 +126,16 @@ class IsRetrievable v o => IsObservable v o | o -> v where
 -- after it completes; when the value changes multiple times it will only be executed once (with the latest value).
 observeBlocking :: (IsObservable v o, MonadResourceManager m) => o -> (ObservableMessage v -> m ()) -> m a
 observeBlocking observable handler = do
+  -- `withSubResourceManagerM` removes the `observe` callback when the `handler` fails.
   withSubResourceManagerM do
     var <- liftIO newEmptyTMVarIO
-    observe observable \msg -> do
-      liftIO $ atomically do
-        cbCompletedVar <- tryTakeTMVar var >>= \case
-          Nothing ->  newAsyncVarSTM
-          Just (_, cbCompletedVar) -> pure cbCompletedVar
-        putTMVar var (msg, cbCompletedVar)
-        pure $ toAwaitable cbCompletedVar
+    observe observable \msg -> liftIO $ atomically do
+      void $ tryTakeTMVar var
+      putTMVar var msg
 
     forever do
-      (msg, cbCompletedVar) <- liftIO $ atomically $ takeTMVar var
-      callback msg
-      putAsyncVar_ cbCompletedVar ()
-
+      msg <- liftIO $ atomically $ takeTMVar var
+      handler msg
 
 
 data ObserveWhileCompleted = ObserveWhileCompleted
@@ -486,7 +481,7 @@ instance IsRetrievable v (ConstObservable v) where
   retrieve (ConstObservable x) = pure $ pure x
 instance IsObservable v (ConstObservable v) where
   observe (ConstObservable x) callback = do
-    void $ callback $ ObservableUpdate x
+    callback $ ObservableUpdate x
 
 
 newtype FailedObservable v = FailedObservable SomeException
@@ -494,7 +489,7 @@ instance IsRetrievable v (FailedObservable v) where
   retrieve (FailedObservable ex) = liftIO $ throwIO ex
 instance IsObservable v (FailedObservable v) where
   observe (FailedObservable ex) callback = do
-    void $ callback $ ObservableNotAvailable ex
+    callback $ ObservableNotAvailable ex
 
 
 -- | Create an observable by simply running an IO action whenever a value is requested or a callback is registered.
-- 
GitLab