packages feed

polysemy-conc 0.6.0.1 → 0.6.1.0

raw patch · 21 files changed

+122/−49 lines, 21 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Polysemy.Conc.Effect.Sync: [ReadBlock] :: Sync d m d
- Polysemy.Conc.Effect.Sync: [ReadTry] :: Sync d m (Maybe d)
- Polysemy.Conc.Effect.Sync: [ReadWait] :: TimeUnit u => u -> Sync d m (Maybe d)
+ Polysemy.Conc: data SyncRead (d :: Type) :: Effect
+ Polysemy.Conc: syncRead :: forall d r. Member (Sync d) r => InterpreterFor (SyncRead d) r
+ Polysemy.Conc.Effect.SyncRead: [Block] :: SyncRead d m d
+ Polysemy.Conc.Effect.SyncRead: [Empty] :: SyncRead d m Bool
+ Polysemy.Conc.Effect.SyncRead: [Try] :: SyncRead d m (Maybe d)
+ Polysemy.Conc.Effect.SyncRead: [Wait] :: TimeUnit u => u -> SyncRead d m (Maybe d)
+ Polysemy.Conc.Effect.SyncRead: data SyncRead (d :: Type) :: Effect
+ Polysemy.Conc.Interpreter.SyncRead: syncRead :: forall d r. Member (Sync d) r => InterpreterFor (SyncRead d) r
+ Polysemy.Conc.Sync: clear :: forall a r. Member (Sync a) r => Sem r ()
+ Polysemy.Conc.SyncRead: data SyncRead (d :: Type) :: Effect
+ Polysemy.Conc.SyncRead: whileEmpty :: forall a r. Member (SyncRead a) r => Sem r () -> Sem r ()
+ Polysemy.Conc.SyncRead: whileEmptyInterval :: forall a u t d r. TimeUnit u => Members [Time t d, SyncRead a] r => u -> Sem r () -> Sem r ()

Files

changelog.md view
@@ -1,5 +1,13 @@ # Unreleased +# 0.6.1.0++* Add `SyncRead`, a read-only variant of `Sync`.+* Change `withAsync` to use `finally` instead of `bracket`, since the latter causes `AsyncCancelled` to be masked,+  preventing the action from being cancelled unless it runs an interruptible action.++# 0.6.0.0+ * Add `Resumable` support for `Scoped`. * Add `Scoped` interpreters that allow the allocator to interpret additional effects used by the handler. 
lib/Polysemy/Conc.hs view
@@ -24,6 +24,7 @@   -- * MVars   -- $mvar   Sync,+  SyncRead,   ScopedSync,    -- ** Interpreters@@ -33,6 +34,7 @@   lock,   interpretScopedSync,   interpretScopedSyncAs,+  syncRead,    -- * Racing   -- $race@@ -194,6 +196,8 @@ import Polysemy.Conc.Race (race_, timeoutAs, timeoutAs_, timeoutMaybe, timeoutU, timeout_) import Polysemy.Conc.Retry (retrying, retryingWithError) import Polysemy.Conc.Sync (lock, withSync)+import Polysemy.Conc.Effect.SyncRead (SyncRead)+import Polysemy.Conc.Interpreter.SyncRead (syncRead)  -- $intro -- This library provides an assortment of tools for concurrency-related tasks:
lib/Polysemy/Conc/Async.hs view
@@ -20,8 +20,9 @@   Sem r b ->   (Base.Async (Maybe b) -> Sem r a) ->   Sem r a-withAsyncBlock mb =-  bracket (async mb) cancel+withAsyncBlock mb use = do+  handle <- async mb+  finally (use handle) (cancel handle)  -- |Run the first action asynchronously while the second action executes, then cancel the first action. -- Passes the handle into the action to allow it to await its result.@@ -34,8 +35,9 @@   Sem r b ->   (Base.Async (Maybe b) -> Sem r a) ->   Sem r a-withAsyncWait interval mb =-  bracket (async mb) (Race.timeoutU interval . cancel)+withAsyncWait interval mb use = do+  handle <- async mb+  finally (use handle) (Race.timeoutU interval (cancel handle))  -- |Run the first action asynchronously while the second action executes, then cancel the first action. -- Passes the handle into the action to allow it to await its result.@@ -86,7 +88,7 @@ scheduleAsync mb f =   withSync @() @res do     h <- async do-      Sync.readBlock @()+      Sync.block @()       raise mb     f h (Sync.putBlock ()) @@ -100,6 +102,6 @@ scheduleAsyncIO mb f =   interpretSync @() do     h <- async do-      Sync.readBlock @()+      Sync.block @()       raise mb     f h (Sync.putBlock ())
lib/Polysemy/Conc/Effect/Critical.hs view
@@ -3,7 +3,7 @@ -- |Description: Critical effect module Polysemy.Conc.Effect.Critical where -import Prelude hiding (catch, run)+import Prelude hiding (catch)  -- |An effect that catches exceptions. --
lib/Polysemy/Conc/Effect/Monitor.hs view
@@ -3,7 +3,6 @@ -- |Description: Monitor Effect, Internal module Polysemy.Conc.Effect.Monitor where -import Control.Concurrent (MVar) import Polysemy.Time (NanoSeconds)  import Polysemy.Conc.Effect.Scoped (Scoped, scoped)
lib/Polysemy/Conc/Effect/Sync.hs view
@@ -1,4 +1,5 @@ {-# options_haddock prune #-}+ -- |Description: Sync effect module Polysemy.Conc.Effect.Sync where @@ -31,12 +32,6 @@   TakeWait :: TimeUnit u => u -> Sync d m (Maybe d)   -- |Take the variable, returning 'Nothing' immmediately if no value was available.   TakeTry :: Sync d m (Maybe d)-  -- |Read the variable, waiting until a value is available.-  ReadBlock :: Sync d m d-  -- |Read the variable, waiting until a value is available or the timeout has expired.-  ReadWait :: TimeUnit u => u -> Sync d m (Maybe d)-  -- |Read the variable, returning 'Nothing' immmediately if no value was available.-  ReadTry :: Sync d m (Maybe d)   -- |Write the variable, waiting until it is writable.   PutBlock :: d -> Sync d m ()   -- |Write the variable, waiting until it is writable or the timeout has expired.
+ lib/Polysemy/Conc/Effect/SyncRead.hs view
@@ -0,0 +1,19 @@+{-# options_haddock prune #-}++-- |The effect 'SyncRead' is equivalent to 'Polysemy.Conc.Sync' without the write actions.+module Polysemy.Conc.Effect.SyncRead where++import Polysemy.Time (TimeUnit)++-- |An interface to a shared variable ('MVar') that can only be read.+data SyncRead (d :: Type) :: Effect where+  -- |Read the variable, waiting until a value is available.+  Block :: SyncRead d m d+  -- |Read the variable, waiting until a value is available or the timeout has expired.+  Wait :: TimeUnit u => u -> SyncRead d m (Maybe d)+  -- |Read the variable, returning 'Nothing' immmediately if no value was available.+  Try :: SyncRead d m (Maybe d)+  -- |Indicate whether the variable is empty.+  Empty :: SyncRead d m Bool++makeSem ''SyncRead
lib/Polysemy/Conc/Interpreter/Critical.hs view
@@ -3,7 +3,6 @@  import qualified Control.Exception as Exception import Polysemy.Final (getInitialStateS, interpretFinal, runS)-import Prelude hiding (Catch)  import Polysemy.Conc.Effect.Critical (Critical (..)) 
lib/Polysemy/Conc/Interpreter/Interrupt.hs view
@@ -3,7 +3,6 @@ -- |Description: Interrupt interpreters module Polysemy.Conc.Interpreter.Interrupt where -import Control.Concurrent (MVar, newEmptyMVar, readMVar, takeMVar, tryPutMVar, tryReadMVar) import qualified Control.Concurrent.Async as A import Control.Concurrent.Async (AsyncCancelled) import Control.Concurrent.STM (TVar, newTVarIO)@@ -12,7 +11,6 @@ import qualified Data.Text.IO as Text import Polysemy.Internal.Tactics (liftT) import Polysemy.Time (Seconds (Seconds))-import Prelude hiding (Catch) import System.IO (stderr) import System.Posix.Signals (   Handler (Catch, CatchInfo, CatchInfoOnce, CatchOnce),
lib/Polysemy/Conc/Interpreter/Monitor.hs view
@@ -3,7 +3,6 @@ -- |Description: Monitor Interpreters, Internal module Polysemy.Conc.Interpreter.Monitor where -import Control.Concurrent (MVar, newEmptyMVar, readMVar, tryTakeMVar) import qualified Control.Exception as Base import qualified Polysemy.Time as Time import Polysemy.Time (Time)
lib/Polysemy/Conc/Interpreter/Scoped.hs view
@@ -9,7 +9,6 @@ import Polysemy.Internal.Union (Weaving (Weaving), decomp, hoist, injWeaving) import Polysemy.Resume (Stop, runStop, type (!!)) import Polysemy.Resume.Data.Resumable (Resumable (Resumable))-import Prelude hiding (run)  import Polysemy.Conc.Effect.Scoped (Scoped (InScope, Run)) 
lib/Polysemy/Conc/Interpreter/Sync.hs view
@@ -1,19 +1,6 @@ -- |Description: Sync Interpreters module Polysemy.Conc.Interpreter.Sync where -import Control.Concurrent (-  MVar,-  isEmptyMVar,-  newEmptyMVar,-  newMVar,-  putMVar,-  readMVar,-  takeMVar,-  tryPutMVar,-  tryReadMVar,-  tryTakeMVar,-  )- import Polysemy.Conc.Effect.Race (Race) import Polysemy.Conc.Effect.Scoped (Scoped) import qualified Polysemy.Conc.Effect.Sync as Sync@@ -41,12 +28,6 @@       rightToMaybe <$> Race.timeoutAs () interval (embed (takeMVar var))     Sync.TakeTry ->       embed (tryTakeMVar var)-    Sync.ReadBlock ->-      embed (readMVar var)-    Sync.ReadWait interval ->-      rightToMaybe <$> Race.timeoutAs () interval (embed (readMVar var))-    Sync.ReadTry ->-      embed (tryReadMVar var)     Sync.PutBlock d ->       embed (putMVar var d)     Sync.PutWait interval d ->
+ lib/Polysemy/Conc/Interpreter/SyncRead.hs view
@@ -0,0 +1,24 @@+-- |Description: Interpreter for 'SyncRead' that reinterprets to 'Sync'.+module Polysemy.Conc.Interpreter.SyncRead where++import qualified Polysemy.Conc.Effect.Sync as Sync+import Polysemy.Conc.Effect.Sync (Sync)+import qualified Polysemy.Conc.Effect.SyncRead as SyncRead+import Polysemy.Conc.Effect.SyncRead (SyncRead)++-- |Run 'SyncRead' in terms of 'Sync'.+syncRead ::+  ∀ d r .+  Member (Sync d) r =>+  InterpreterFor (SyncRead d) r+syncRead =+  interpret \case+    SyncRead.Block ->+      Sync.block+    SyncRead.Wait u ->+      Sync.wait u+    SyncRead.Try ->+      Sync.try+    SyncRead.Empty ->+      Sync.empty @d+{-# inline syncRead #-}
lib/Polysemy/Conc/Monitor.hs view
@@ -3,7 +3,6 @@ -- |Description: Monitor Implementations, Internal module Polysemy.Conc.Monitor where -import Control.Concurrent (tryPutMVar) import qualified Polysemy.Time as Time import Polysemy.Time (Minutes (Minutes), NanoSeconds, Seconds (Seconds), Time, TimeUnit, convert) import Torsor (Torsor, difference, minus)
lib/Polysemy/Conc/Sync.hs view
@@ -1,8 +1,9 @@ {-# options_haddock prune #-}+ -- |Description: Sync Combinators module Polysemy.Conc.Sync (   module Polysemy.Conc.Sync,-  module Polysemy.Conc.Effect.Sync+  module Polysemy.Conc.Effect.Sync, ) where  import qualified Polysemy.Time as Time@@ -19,9 +20,6 @@   putBlock,   putTry,   putWait,-  readBlock,-  readTry,-  readWait,   takeBlock,   takeTry,   takeWait,@@ -58,6 +56,7 @@       whenM (not <$> Sync.empty @a) (Time.sleep @t @d interval *> spin)  -- |Run an action with a locally scoped 'Sync' variable.+-- This avoids a dependency on @'Embed' 'IO'@ in application logic while still allowing the variable to be scoped. withSync ::   ∀ d res r .   Member (ScopedSync res d) r =>@@ -79,3 +78,11 @@   Sem r a lock l ma =   finally (takeBlock @l *> ma) (putTry l)++-- |Remove the content of the 'Sync' variable if it is present.+clear ::+  ∀ a r .+  Member (Sync a) r =>+  Sem r ()+clear =+  void (takeTry @a)
+ lib/Polysemy/Conc/SyncRead.hs view
@@ -0,0 +1,41 @@+{-# options_haddock prune #-}++-- |Description: API and combinators for 'SyncRead'.+module Polysemy.Conc.SyncRead (+  module Polysemy.Conc.SyncRead,+  module Polysemy.Conc.Effect.SyncRead,+) where++import qualified Polysemy.Time as Time+import Polysemy.Time (Time, TimeUnit)++import qualified Polysemy.Conc.Effect.SyncRead as SyncRead+import Polysemy.Conc.Effect.SyncRead (SyncRead, block, empty, try, wait)++-- |Run an action repeatedly until the 'SyncRead' variable is available.+whileEmpty ::+  ∀ a r .+  Member (SyncRead a) r =>+  Sem r () ->+  Sem r ()+whileEmpty action =+  spin+  where+    spin = do+      action+      whenM (not <$> SyncRead.empty @a) spin++-- |Run an action repeatedly until the 'SyncRead' variable is available, waiting for the specified time between executions.+whileEmptyInterval ::+  ∀ a u t d r .+  TimeUnit u =>+  Members [Time t d, SyncRead a] r =>+  u ->+  Sem r () ->+  Sem r ()+whileEmptyInterval interval action =+  spin+  where+    spin = do+      action+      whenM (not <$> SyncRead.empty @a) (Time.sleep @t @d interval *> spin)
polysemy-conc.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           polysemy-conc-version:        0.6.0.1+version:        0.6.1.0 synopsis:       Polysemy Effects for Concurrency description:    See <https://hackage.haskell.org/package/polysemy-conc/docs/Polysemy-Conc.html> category:       Concurrency@@ -40,6 +40,7 @@       Polysemy.Conc.Effect.Race       Polysemy.Conc.Effect.Scoped       Polysemy.Conc.Effect.Sync+      Polysemy.Conc.Effect.SyncRead       Polysemy.Conc.Events       Polysemy.Conc.Interpreter.Critical       Polysemy.Conc.Interpreter.Events@@ -53,6 +54,7 @@       Polysemy.Conc.Interpreter.Scoped       Polysemy.Conc.Interpreter.Stack       Polysemy.Conc.Interpreter.Sync+      Polysemy.Conc.Interpreter.SyncRead       Polysemy.Conc.Monitor       Polysemy.Conc.Queue       Polysemy.Conc.Queue.Result@@ -60,6 +62,7 @@       Polysemy.Conc.Race       Polysemy.Conc.Retry       Polysemy.Conc.Sync+      Polysemy.Conc.SyncRead   hs-source-dirs:       lib   default-extensions:
test/Polysemy/Conc/Test/InterruptTest.hs view
@@ -1,6 +1,5 @@ module Polysemy.Conc.Test.InterruptTest where -import Control.Concurrent (MVar, newEmptyMVar, putMVar, takeMVar) import Control.Concurrent.STM (TVar, atomically, modifyTVar, newTVarIO, readTVarIO) import Polysemy.Test (UnitTest, assertEq, runTestAuto) import System.Posix (Handler (CatchInfoOnce), SignalInfo, installHandler, keyboardSignal, raiseSignal)
test/Polysemy/Conc/Test/MonitorTest.hs view
@@ -2,7 +2,6 @@  module Polysemy.Conc.Test.MonitorTest where -import Control.Concurrent (MVar, putMVar) import Data.Time (UTCTime) import Polysemy.Test (UnitTest, assertEq, assertJust, runTestAuto) import qualified Polysemy.Time as Time
test/Polysemy/Conc/Test/QueueTest.hs view
@@ -2,8 +2,7 @@  import Polysemy.Test (UnitTest, assertEq, assertJust, runTestAuto) import Polysemy.Time (MilliSeconds (MilliSeconds), interpretTimeGhc)-import Polysemy.Time.Ghc (GhcTime)-import Prelude hiding (run)+import Polysemy.Time.Interpreter.Ghc (GhcTime)  import qualified Polysemy.Conc.Data.QueueResult as QueueResult import Polysemy.Conc.Data.QueueResult (QueueResult)
test/Polysemy/Conc/Test/SyncTest.hs view
@@ -1,7 +1,6 @@ module Polysemy.Conc.Test.SyncTest where  import Polysemy.Test (UnitTest, assertEq, runTestAuto)-import Prelude hiding (run)  import Polysemy.Conc.Effect.Race (Race) import qualified Polysemy.Conc.Effect.Sync as Sync