packages feed

polysemy-conc 0.8.0.1 → 0.9.0.0

raw patch · 10 files changed

+163/−97 lines, 10 filesdep +hedgehogdep +tasty-hedgehogdep ~basedep ~incipit-corePVP ok

version bump matches the API change (PVP)

Dependencies added: hedgehog, tasty-hedgehog

Dependency ranges changed: base, incipit-core

API changes (from Hackage documentation)

+ Polysemy.Conc: data Restoration
+ Polysemy.Conc: interpretScopedResumableWith :: forall extra resource effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => InsertAtIndex 1 '[Scoped resource effect !! err] r1 r ((Scoped resource effect !! err) : r1) (extra ++ '[Stop err]) => (forall x. (resource -> Sem r1 x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem r1 x) -> InterpreterFor (Scoped resource effect !! err) r
+ Polysemy.Conc: interpretScopedResumableWithH :: forall extra resource effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => InsertAtIndex 1 '[Scoped resource effect !! err] r1 r ((Scoped resource effect !! err) : r1) (extra ++ '[Stop err]) => (forall x. (resource -> Sem r1 x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) r1 x) -> InterpreterFor (Scoped resource effect !! err) r
+ Polysemy.Conc: interpretScopedResumableWith_ :: forall extra effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => InsertAtIndex 1 '[Scoped () effect !! err] r1 r ((Scoped () effect !! err) : r1) (extra ++ '[Stop err]) => (forall x. Sem r1 x -> Sem (Stop err : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem r1 x) -> InterpreterFor (Scoped () effect !! err) r
+ Polysemy.Conc: interpretScopedWith :: forall extra resource effect r r1. r1 ~ (extra ++ r) => InsertAtIndex 1 '[Scoped resource effect] r1 r (Scoped resource effect : r1) extra => (forall x. (resource -> Sem r1 x) -> Sem r x) -> (forall m x. resource -> effect m x -> Sem r1 x) -> InterpreterFor (Scoped resource effect) r
+ Polysemy.Conc: interpretScopedWithH :: forall extra resource effect r r1. r1 ~ (extra ++ r) => InsertAtIndex 1 '[Scoped resource effect] r1 r (Scoped resource effect : r1) extra => (forall x. (resource -> Sem r1 x) -> Sem r x) -> (forall m x. resource -> effect m x -> Tactical effect m r1 x) -> InterpreterFor (Scoped resource effect) r
+ Polysemy.Conc: interpretScopedWith_ :: forall extra effect r r1. r1 ~ (extra ++ r) => InsertAtIndex 1 '[Scoped () effect] r1 r (Scoped () effect : r1) extra => (forall x. Sem r1 x -> Sem r x) -> (forall m x. effect m x -> Sem r1 x) -> InterpreterFor (Scoped () effect) r
+ Polysemy.Conc.Interpreter.Mask: Restoration :: (forall a. IO a -> IO a) -> Restoration
+ Polysemy.Conc.Interpreter.Mask: [$sel:unRestoration:Restoration] :: Restoration -> forall a. IO a -> IO a
+ Polysemy.Conc.Interpreter.Mask: newtype Restoration
+ Polysemy.Conc.Sync: modify :: forall a b res r. Members [Sync a, Mask res, Resource] r => (a -> Sem r (a, b)) -> Sem r b
+ Polysemy.Conc.Sync: modifyMasked :: forall a b res r. Members [Sync a, Mask res, Resource] r => (a -> Sem r (a, b)) -> Sem r b
+ Polysemy.Conc.Sync: modifyMasked_ :: forall a res r. Members [Sync a, Mask res, Resource] r => (a -> Sem r a) -> Sem r ()
+ Polysemy.Conc.Sync: modify_ :: forall a res r. Members [Sync a, Mask res, Resource] r => (a -> Sem r a) -> Sem r ()
+ Polysemy.Conc.Sync: use :: forall a b res r. Members [Sync a, Mask res, Resource] r => (a -> Sem r b) -> Sem r b
+ Polysemy.Conc.Sync: useMasked :: forall a b res r. Members [Sync a, Mask res, Resource] r => (a -> Sem r b) -> Sem r b

Files

− changelog.md
@@ -1,42 +0,0 @@-# 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.--# 0.5.0.0--* Add `mask` effects.-* Add `Monitor`, an effect that repeatedly checks a condition and restarts a region when it is met.-* Add interpreter combinators for `Scoped`.-* Add a runner for the default `Conc` stack.--# 0.4.0.0--* Add `lock`, a combinator for protecting a region with a mutex.-* Add `scheduleAsync`, a combinator for running an action async that allows the handle to be used before the thread-  starts-* Change the default signal handler for `Interrupt` to `CatchInfo`, catching repeated signals.--# 0.3.0.0--* Change `Race.timeout` to take a `Sem` for the fallback instead of a pure value.-* Export all `Queue` constructors from `Polysemy.Conc.Queue`.-* Export all `Sync` constructors from `Polysemy.Conc.Sync`.-* Move all interpreters to `Polysemy.Conc.Interpreter`.--# 0.2.0.0-* Add `read*` constructors for `Sync`-* Add `subscribeWhile`, a combinator that consumes events until a condition is met-* Add looping combinators for `Queue`-* Add `retry`, a combinator that runs an action repeatedly until it returns `Right` or a timeout is hit-* Add `Scoped`, an effect for local resource scoping-* Add `withAsync`, a bracketing combinator that runs an async action while the main action runs-* Add `interpretAtomic`, a convenience interpreter for `AtomicState` that runs `runAtomicStateTVar`
lib/Polysemy/Conc.hs view
@@ -92,6 +92,7 @@   mask,   uninterruptibleMask,   restore,+  Restoration,    -- * Interpreters   interpretMaskFinal,@@ -109,6 +110,12 @@   interpretScopedAs,   interpretScopedResumable,   interpretScopedResumableH,+  interpretScopedWith,+  interpretScopedWithH,+  interpretScopedWith_,+  interpretScopedResumableWith,+  interpretScopedResumableWithH,+  interpretScopedResumableWith_,    -- * Monitoring   Monitor,@@ -170,7 +177,7 @@ import Polysemy.Conc.Interpreter.Critical (interpretCritical, interpretCriticalNull) import Polysemy.Conc.Interpreter.Events (ChanConsumer, ChanEvents, EventChan, EventConsumer, interpretEventsChan) import Polysemy.Conc.Interpreter.Interrupt (interpretInterrupt, interpretInterruptNull, interpretInterruptOnce)-import Polysemy.Conc.Interpreter.Mask (interpretMaskFinal, interpretUninterruptibleMaskFinal)+import Polysemy.Conc.Interpreter.Mask (Restoration, interpretMaskFinal, interpretUninterruptibleMaskFinal) import Polysemy.Conc.Interpreter.Monitor (interpretMonitorPure, interpretMonitorRestart) import Polysemy.Conc.Interpreter.Queue.Pure (   interpretQueueListReadOnlyAtomic,@@ -187,6 +194,12 @@   interpretScopedH,   interpretScopedResumable,   interpretScopedResumableH,+  interpretScopedResumableWith,+  interpretScopedResumableWithH,+  interpretScopedResumableWith_,+  interpretScopedWith,+  interpretScopedWithH,+  interpretScopedWith_,   runScoped,   runScopedAs,   )
lib/Polysemy/Conc/Interpreter/Mask.hs view
@@ -15,6 +15,7 @@   ) import Polysemy.Conc.Interpreter.Scoped (runScoped) +-- |Resource type for the scoped 'Mask' effect, wrapping the @restore@ callback passed in by 'Base.mask'. newtype Restoration =   Restoration { unRestoration :: ∀ a . IO a -> IO a } @@ -24,7 +25,7 @@   Sem r a mask f =   withWeavingToFinal @IO \ s lower _ ->-    Base.mask \ restore -> (lower (f (MaskResource (Restoration restore)) <$ s))+    Base.mask \ restore -> lower (f (MaskResource (Restoration restore)) <$ s)  uninterruptibleMask ::   Member (Final IO) r =>@@ -32,7 +33,7 @@   Sem r a uninterruptibleMask f =   withWeavingToFinal @IO \ s lower _ ->-    Base.uninterruptibleMask \ restore -> (lower (f (UninterruptibleMaskResource (Restoration restore)) <$ s))+    Base.uninterruptibleMask \ restore -> lower (f (UninterruptibleMaskResource (Restoration restore)) <$ s)  interpretRestoreMask ::   ∀ r .@@ -44,8 +45,7 @@     Restore ma -> do       let         restoreSem m =-          withStrategicToFinal do-            (restore <$> runS m)+          withStrategicToFinal (restore <$> runS m)       restoreSem (runTSimple ma)  -- |Interpret 'Mask' in 'IO'.
lib/Polysemy/Conc/Interpreter/Scoped.hs view
@@ -8,7 +8,7 @@ import Polysemy.Internal.Tactics (liftT, runTactics) import Polysemy.Internal.Union (Weaving (Weaving), decomp, hoist, injWeaving) import Polysemy.Resume (Stop, runStop, type (!!))-import Polysemy.Resume.Data.Resumable (Resumable (Resumable))+import Polysemy.Resume.Effect.Resumable (Resumable (Resumable))  import Polysemy.Conc.Effect.Scoped (Scoped (InScope, Run)) 
lib/Polysemy/Conc/Sync.hs view
@@ -9,6 +9,7 @@ import qualified Polysemy.Time as Time import Polysemy.Time (Time, TimeUnit) +import Polysemy.Conc.Effect.Mask (Mask, mask, restore) import Polysemy.Conc.Effect.Scoped (scoped) import qualified Polysemy.Conc.Effect.Sync as Sync import Polysemy.Conc.Effect.Sync (@@ -78,6 +79,7 @@   Sem r a lock l ma =   finally (takeBlock @l *> ma) (putTry l)+{-# inline lock #-}  -- |Remove the content of the 'Sync' variable if it is present. clear ::@@ -86,3 +88,91 @@   Sem r () clear =   void (takeTry @a)+{-# inline clear #-}++-- |Modify a 'Sync' variable with async exceptions masked for the 'Sync' operations, but not the action.+-- Allows a value to be returned.+-- Equivalent to 'Control.Concurrent.MVar.modifyMVar'.+modify ::+  ∀ a b res r .+  Members [Sync a, Mask res, Resource] r =>+  (a -> Sem r (a, b)) ->+  Sem r b+modify m =+  mask @res do+    a <- takeBlock+    (a', b) <- onException (restore (raise (m a))) (putBlock a)+    b <$ putBlock a'+{-# inline modify #-}++-- |Modify a 'Sync' variable with async exceptions masked for the 'Sync' operations, but not the action.+-- Does not allow a value to be returned.+-- Equivalent to 'Control.Concurrent.MVar.modifyMVar_'.+modify_ ::+  ∀ a res r .+  Members [Sync a, Mask res, Resource] r =>+  (a -> Sem r a) ->+  Sem r ()+modify_ m =+  mask @res do+    a <- takeBlock+    a' <- onException (restore (raise (m a))) (putBlock a)+    putBlock a'+{-# inline modify_ #-}++-- |Modify a 'Sync' variable with async exceptions masked for the entire procedure.+-- Allows a value to be returned.+-- Equivalent to 'Control.Concurrent.MVar.modifyMVarMasked'.+modifyMasked ::+  ∀ a b res r .+  Members [Sync a, Mask res, Resource] r =>+  (a -> Sem r (a, b)) ->+  Sem r b+modifyMasked m =+  mask @res do+    a <- takeBlock+    (a', b) <- onException (raise (m a)) (putBlock a)+    b <$ putBlock a'+{-# inline modifyMasked #-}++-- |Modify a 'Sync' variable with async exceptions masked for the entire procedure.+-- Does not allow a value to be returned.+-- Equivalent to 'Control.Concurrent.MVar.modifyMVarMasked_'.+modifyMasked_ ::+  ∀ a res r .+  Members [Sync a, Mask res, Resource] r =>+  (a -> Sem r a) ->+  Sem r ()+modifyMasked_ m =+  mask @res do+    a <- takeBlock+    a' <- onException (raise (m a)) (putBlock a)+    putBlock a'+{-# inline modifyMasked_ #-}++-- |Run an action with the current value of the 'Sync' variable with async exceptions masked for the 'Sync' operations,+-- but not the action.+-- Equivalent to 'Control.Concurrent.MVar.withMVar'.+use ::+  ∀ a b res r .+  Members [Sync a, Mask res, Resource] r =>+  (a -> Sem r b) ->+  Sem r b+use m =+  mask @res do+    a <- takeBlock+    finally (restore (raise (m a))) (putBlock a)+{-# inline use #-}++-- |Run an action with the current value of the 'Sync' variable with async exceptions masked for the entire procedure.+-- Equivalent to 'Control.Concurrent.MVar.withMVarMasked'.+useMasked ::+  ∀ a b res r .+  Members [Sync a, Mask res, Resource] r =>+  (a -> Sem r b) ->+  Sem r b+useMasked m =+  mask @res do+    a <- takeBlock+    finally (raise (m a)) (putBlock a)+{-# inline useMasked #-}
polysemy-conc.cabal view
@@ -5,21 +5,18 @@ -- see: https://github.com/sol/hpack  name:           polysemy-conc-version:        0.8.0.1-synopsis:       Polysemy Effects for Concurrency-description:    See <https://hackage.haskell.org/package/polysemy-conc/docs/Polysemy-Conc.html>+version:        0.9.0.0+synopsis:       Polysemy effects for concurrency+description:    See https://hackage.haskell.org/package/polysemy-conc/docs/Polysemy-Conc.html category:       Concurrency homepage:       https://github.com/tek/polysemy-conc#readme bug-reports:    https://github.com/tek/polysemy-conc/issues author:         Torsten Schmits-maintainer:     haskell@tryp.io-copyright:      2021 Torsten Schmits+maintainer:     hackage@tryp.io+copyright:      2022 Torsten Schmits license:        BSD-2-Clause-Patent license-file:   LICENSE build-type:     Simple-extra-source-files:-    readme.md-    changelog.md  source-repository head   type: git@@ -79,6 +76,7 @@       DeriveFoldable       DeriveFunctor       DeriveGeneric+      DeriveLift       DeriveTraversable       DerivingStrategies       DerivingVia@@ -111,6 +109,7 @@       RankNTypes       RecordWildCards       RecursiveDo+      RoleAnnotations       ScopedTypeVariables       StandaloneDeriving       TemplateHaskell@@ -123,12 +122,12 @@       UndecidableInstances       UnicodeSyntax       ViewPatterns-  ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Widentities+  ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Widentities -Wunused-packages   build-depends:       async-    , base ==4.*+    , base >=4.12 && <5     , containers-    , incipit-core >=0.2+    , incipit-core >=0.3     , polysemy >=1.6     , polysemy-resume >=0.3     , polysemy-time >=0.3@@ -139,8 +138,8 @@     , unix   mixins:       base hiding (Prelude)-  if impl(ghc >= 8.10)-    ghc-options: -Wunused-packages+    , incipit-core (IncipitCore as Prelude)+    , incipit-core hiding (IncipitCore)   default-language: Haskell2010  test-suite polysemy-conc-unit@@ -171,6 +170,7 @@       DeriveFoldable       DeriveFunctor       DeriveGeneric+      DeriveLift       DeriveTraversable       DerivingStrategies       DerivingVia@@ -203,6 +203,7 @@       RankNTypes       RecordWildCards       RecursiveDo+      RoleAnnotations       ScopedTypeVariables       StandaloneDeriving       TemplateHaskell@@ -215,11 +216,12 @@       UndecidableInstances       UnicodeSyntax       ViewPatterns-  ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Widentities -threaded -rtsopts -with-rtsopts=-N+  ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Widentities -Wunused-packages -threaded -rtsopts -with-rtsopts=-N   build-depends:       async-    , base ==4.*-    , incipit-core+    , base >=4.12 && <5+    , hedgehog+    , incipit-core >=0.3     , polysemy     , polysemy-conc     , polysemy-plugin@@ -228,11 +230,12 @@     , polysemy-time     , stm     , tasty+    , tasty-hedgehog     , time     , unagi-chan     , unix   mixins:       base hiding (Prelude)-  if impl(ghc >= 8.10)-    ghc-options: -Wunused-packages+    , incipit-core (IncipitCore as Prelude)+    , incipit-core hiding (IncipitCore)   default-language: Haskell2010
− readme.md
@@ -1,8 +0,0 @@-# About--This library provides [Polysemy] effects for using STM queues, MVars, signal handling and racing.--Please visit [Hackage] for documentation.--[Polysemy]: https://hackage.haskell.org/package/polysemy-[Hackage]: https://hackage.haskell.org/package/polysemy-conc/docs/Polysemy-Conc.html
test/Main.hs view
@@ -1,5 +1,6 @@ module Main where +import Hedgehog (property, test, withTests) import Polysemy.Conc.Test.EventsTest (test_events) import Polysemy.Conc.Test.InterruptTest (test_interrupt) import Polysemy.Conc.Test.MaskTest (test_mask)@@ -16,6 +17,7 @@ import Polysemy.Conc.Test.SyncTest (test_sync) import Polysemy.Test (unitTest) import Test.Tasty (TestTree, defaultMain, testGroup)+import Test.Tasty.Hedgehog (testProperty)  tests :: TestTree tests =@@ -29,7 +31,7 @@       unitTest "TB block" test_queueBlockTB     ],     testGroup "events" [-      unitTest "events" test_events+      testProperty "events" (withTests 100 (property (test test_events)))     ],     testGroup "sync" [       unitTest "sync" test_sync
test/Polysemy/Conc/Test/EventsTest.hs view
@@ -11,24 +11,33 @@  test_events :: UnitTest test_events =-  (runTestAuto . asyncToIOFinal) do-    interpretRace $ interpretSync @() $ interpretEventsChan @Int $ interpretEventsChan @Text do-      thread1 <- async do-        Events.subscribe @Int @(OutChan Int) do-          Events.consume @Int-      thread2 <- async do-        Events.subscribe @Int @(OutChan Int) do-          Events.consume @Int-      thread3 <- async do-        Events.subscribe @Text @(OutChan Text) do-          Sync.putBlock ()-          Events.consume @Text-      Sync.takeBlock @()-      Events.publish @Text @(OutChan Text) "test"-      Events.publish @Int @(OutChan Int) 1-      num1 <- await thread1-      num2 <- await thread2-      text1 <- await thread3-      assertJust @_ @IO 1 num1-      assertJust @_ @IO 1 num2-      assertJust @_ @IO "test" text1+  (runTestAuto . asyncToIOFinal) $+  interpretRace $+  interpretSync @(Proxy 1) $+  interpretSync @(Proxy 2) $+  interpretSync @(Proxy 3) $+  interpretEventsChan @Int $+  interpretEventsChan @Text do+    thread1 <- async do+      Events.subscribe @Int @(OutChan Int) do+        Sync.putBlock (Proxy @1)+        Events.consume @Int+    thread2 <- async do+      Events.subscribe @Int @(OutChan Int) do+        Sync.putBlock (Proxy @2)+        Events.consume @Int+    thread3 <- async do+      Events.subscribe @Text @(OutChan Text) do+        Sync.putBlock (Proxy @3)+        Events.consume @Text+    Sync.takeBlock @(Proxy 1)+    Sync.takeBlock @(Proxy 2)+    Sync.takeBlock @(Proxy 3)+    Events.publish @Text @(OutChan Text) "test"+    Events.publish @Int @(OutChan Int) 1+    num1 <- await thread1+    num2 <- await thread2+    text1 <- await thread3+    assertJust @_ @IO 1 num1+    assertJust @_ @IO 1 num2+    assertJust @_ @IO "test" text1
test/Polysemy/Conc/Test/MaskTest.hs view
@@ -5,7 +5,6 @@ import qualified Control.Concurrent.Async as Base import Control.Concurrent.Async (asyncThreadId) import Control.Exception (throwTo)-import GHC.Stack (withFrozenCallStack) import Polysemy.Test (Hedgehog, UnitTest, assertEq, evalLeft, runTestAuto) import qualified Polysemy.Time as Time import Polysemy.Time (MilliSeconds (MilliSeconds), interpretTimeGhc)