packages feed

extensible-effects-concurrent 0.13.0 → 0.13.2

raw patch · 12 files changed

+478/−45 lines, 12 filesdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base

API changes (from Hackage documentation)

- Control.Eff.Concurrent: -- <a>ProcessId</a>s in a type safe way, e.g. for a tuple instance of
- Control.Eff.Concurrent: -- this class <tt>(Server a, Server b)</tt>
- Control.Eff.Concurrent: class Servable a where {
- Control.Eff.Concurrent: toServerCallback :: (Servable a, Member Interrupts (ServerEff a), SetMember Process (Process effScheduler) (ServerEff a)) => SchedulerProxy effScheduler -> a -> ServerCallback (ServerEff a)
+ Control.Eff.Concurrent: (^:) :: forall (api1 :: Type) (apis2 :: [Type]) eff. HasCallStack => MessageCallback api1 eff -> MessageCallback apis2 eff -> MessageCallback (api1 : apis2) eff
+ Control.Eff.Concurrent: [HandleNext] :: CallbackResult
+ Control.Eff.Concurrent: [InterruptCallback] :: (InterruptReason -> Eff eff CallbackResult) -> InterruptCallback eff
+ Control.Eff.Concurrent: [MessageCallback] :: MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent: [ProcessFinished] :: ExitReason 'Recoverable
+ Control.Eff.Concurrent: [StopServer] :: InterruptReason -> CallbackResult
+ Control.Eff.Concurrent: class ToServerPids (t :: k) where {
+ Control.Eff.Concurrent: data CallbackResult
+ Control.Eff.Concurrent: data InterruptCallback eff
+ Control.Eff.Concurrent: data MessageCallback api eff
+ Control.Eff.Concurrent: dropUnhandledMessages :: forall eff. HasCallStack => MessageCallback '[] eff
+ Control.Eff.Concurrent: exitOnUnhandled :: forall eff. HasCallStack => MessageCallback '[] eff
+ Control.Eff.Concurrent: fallbackHandler :: forall api eff. HasCallStack => MessageCallback api eff -> MessageCallback '[] eff
+ Control.Eff.Concurrent: handleAnyMessages :: forall eff. HasCallStack => (Dynamic -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent: handleCalls :: forall api eff reply. (HasCallStack, NFData (Api api ( 'Synchronous reply)), Typeable (Api api ( 'Synchronous reply))) => (Api api ( 'Synchronous reply) -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent: handleCasts :: forall api eff. (HasCallStack, NFData (Api api 'Asynchronous), Typeable (Api api 'Asynchronous)) => (Api api 'Asynchronous -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent: handleCastsAndCalls :: forall api eff reply. (HasCallStack, NFData (Api api ( 'Synchronous reply)), Typeable (Api api ( 'Synchronous reply)), NFData (Api api 'Asynchronous), Typeable (Api api 'Asynchronous)) => (Api api 'Asynchronous -> Eff eff CallbackResult) -> (Api api ( 'Synchronous reply) -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent: handleMessages :: forall eff a. (HasCallStack, NFData a, Typeable a) => (a -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent: handleProcessDowns :: forall eff. HasCallStack => (MonitorReference -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent: handleSelectedMessages :: forall eff a. HasCallStack => MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent: infixr 5 ^:
+ Control.Eff.Concurrent: logUnhandledMessages :: forall eff. (Member (Logs LogMessage) eff, HasCallStack) => MessageCallback '[] eff
+ Control.Eff.Concurrent: spawnApiServer :: forall api eff. (ToServerPids api, HasCallStack) => MessageCallback api (InterruptableProcess eff) -> InterruptCallback (ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api)
+ Control.Eff.Concurrent: spawnApiServerEffectful :: forall api eff serverEff. (HasCallStack, Member Interrupts serverEff, SetMember Process (Process eff) serverEff) => (forall b. Eff serverEff b -> Eff (InterruptableProcess eff) b) -> MessageCallback api serverEff -> InterruptCallback serverEff -> Eff (InterruptableProcess eff) (Server api)
+ Control.Eff.Concurrent: spawnApiServerStateful :: forall api eff state. HasCallStack => Eff (InterruptableProcess eff) state -> MessageCallback api (State state : InterruptableProcess eff) -> InterruptCallback (State state : ConsProcess eff) -> Eff (InterruptableProcess eff) (Server api)
+ Control.Eff.Concurrent: stopServerOnInterrupt :: forall eff. HasCallStack => InterruptCallback eff
+ Control.Eff.Concurrent: tryUninterrupted :: (HasCallStack, Member Interrupts r) => Eff r a -> Eff r (Either InterruptReason a)
+ Control.Eff.Concurrent.Api.Server2: (^:) :: forall (api1 :: Type) (apis2 :: [Type]) eff. HasCallStack => MessageCallback api1 eff -> MessageCallback apis2 eff -> MessageCallback (api1 : apis2) eff
+ Control.Eff.Concurrent.Api.Server2: [HandleNext] :: CallbackResult
+ Control.Eff.Concurrent.Api.Server2: [InterruptCallback] :: (InterruptReason -> Eff eff CallbackResult) -> InterruptCallback eff
+ Control.Eff.Concurrent.Api.Server2: [MessageCallback] :: MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent.Api.Server2: [StopServer] :: InterruptReason -> CallbackResult
+ Control.Eff.Concurrent.Api.Server2: class ToServerPids (t :: k) where {
+ Control.Eff.Concurrent.Api.Server2: data CallbackResult
+ Control.Eff.Concurrent.Api.Server2: data InterruptCallback eff
+ Control.Eff.Concurrent.Api.Server2: data MessageCallback api eff
+ Control.Eff.Concurrent.Api.Server2: dropUnhandledMessages :: forall eff. HasCallStack => MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: exitOnUnhandled :: forall eff. HasCallStack => MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: fallbackHandler :: forall api eff. HasCallStack => MessageCallback api eff -> MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: handleAnyMessages :: forall eff. HasCallStack => (Dynamic -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: handleCalls :: forall api eff reply. (HasCallStack, NFData (Api api ( 'Synchronous reply)), Typeable (Api api ( 'Synchronous reply))) => (Api api ( 'Synchronous reply) -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent.Api.Server2: handleCasts :: forall api eff. (HasCallStack, NFData (Api api 'Asynchronous), Typeable (Api api 'Asynchronous)) => (Api api 'Asynchronous -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent.Api.Server2: handleCastsAndCalls :: forall api eff reply. (HasCallStack, NFData (Api api ( 'Synchronous reply)), Typeable (Api api ( 'Synchronous reply)), NFData (Api api 'Asynchronous), Typeable (Api api 'Asynchronous)) => (Api api 'Asynchronous -> Eff eff CallbackResult) -> (Api api ( 'Synchronous reply) -> Eff eff CallbackResult) -> MessageCallback api eff
+ Control.Eff.Concurrent.Api.Server2: handleMessages :: forall eff a. (HasCallStack, NFData a, Typeable a) => (a -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: handleProcessDowns :: forall eff. HasCallStack => (MonitorReference -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: handleSelectedMessages :: forall eff a. HasCallStack => MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: infixr 5 ^:
+ Control.Eff.Concurrent.Api.Server2: instance (Control.Eff.Concurrent.Api.Server2.ToServerPids api1, Control.Eff.Concurrent.Api.Server2.ToServerPids api2) => Control.Eff.Concurrent.Api.Server2.ToServerPids (api1 : api2)
+ Control.Eff.Concurrent.Api.Server2: instance Control.DeepSeq.NFData Control.Eff.Concurrent.Api.Server2.CallbackResult
+ Control.Eff.Concurrent.Api.Server2: instance Control.Eff.Concurrent.Api.Server2.ToServerPids '[]
+ Control.Eff.Concurrent.Api.Server2: instance Control.Eff.Concurrent.Api.Server2.ToServerPids api1 => Control.Eff.Concurrent.Api.Server2.ToServerPids api1
+ Control.Eff.Concurrent.Api.Server2: instance Data.Default.Class.Default (Control.Eff.Concurrent.Api.Server2.InterruptCallback eff)
+ Control.Eff.Concurrent.Api.Server2: instance GHC.Generics.Generic Control.Eff.Concurrent.Api.Server2.CallbackResult
+ Control.Eff.Concurrent.Api.Server2: instance GHC.Show.Show Control.Eff.Concurrent.Api.Server2.CallbackResult
+ Control.Eff.Concurrent.Api.Server2: instance forall k (api :: k) (eff :: [* -> *]). Data.Default.Class.Default (Control.Eff.Concurrent.Api.Server2.MessageCallback api eff)
+ Control.Eff.Concurrent.Api.Server2: instance forall k (api :: k) (eff :: [* -> *]). GHC.Base.Monoid (Control.Eff.Concurrent.Api.Server2.MessageCallback api eff)
+ Control.Eff.Concurrent.Api.Server2: instance forall k (api :: k) (eff :: [* -> *]). GHC.Base.Semigroup (Control.Eff.Concurrent.Api.Server2.MessageCallback api eff)
+ Control.Eff.Concurrent.Api.Server2: logUnhandledMessages :: forall eff. (Member (Logs LogMessage) eff, HasCallStack) => MessageCallback '[] eff
+ Control.Eff.Concurrent.Api.Server2: spawnApiServer :: forall api eff. (ToServerPids api, HasCallStack) => MessageCallback api (InterruptableProcess eff) -> InterruptCallback (ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api)
+ Control.Eff.Concurrent.Api.Server2: spawnApiServerEffectful :: forall api eff serverEff. (HasCallStack, Member Interrupts serverEff, SetMember Process (Process eff) serverEff) => (forall b. Eff serverEff b -> Eff (InterruptableProcess eff) b) -> MessageCallback api serverEff -> InterruptCallback serverEff -> Eff (InterruptableProcess eff) (Server api)
+ Control.Eff.Concurrent.Api.Server2: spawnApiServerStateful :: forall api eff state. HasCallStack => Eff (InterruptableProcess eff) state -> MessageCallback api (State state : InterruptableProcess eff) -> InterruptCallback (State state : ConsProcess eff) -> Eff (InterruptableProcess eff) (Server api)
+ Control.Eff.Concurrent.Api.Server2: stopServerOnInterrupt :: forall eff. HasCallStack => InterruptCallback eff
+ Control.Eff.Concurrent.Api.Server2: toServerPids :: ToServerPids t => proxy t -> ProcessId -> ServerPids t
+ Control.Eff.Concurrent.Api.Server2: type family ServerPids t;
+ Control.Eff.Concurrent.Api.Server2: }
+ Control.Eff.Concurrent.Process: [ProcessFinished] :: ExitReason 'Recoverable
+ Control.Eff.Concurrent.Process: tryUninterrupted :: (HasCallStack, Member Interrupts r) => Eff r a -> Eff r (Either InterruptReason a)
- Control.Eff.Concurrent: [ApiHandler] :: {_castCallback :: Maybe (Api api 'Asynchronous -> Eff eff ApiServerCmd) " A cast will not return a result directly. This is used for async methods. This returns an 'ApiServerCmd' to the server loop.", _callCallback :: forall reply. Maybe (Api api ( 'Synchronous reply) -> (reply -> Eff eff ()) -> Eff eff ApiServerCmd) " A call is a blocking operation, the caller is blocked until this handler calls the reply continuation. This returns an 'ApiServerCmd' to the server loop.", _terminateCallback :: Maybe (ExitReason 'Recoverable -> Eff eff ()) " This callback is called with @Nothing@ if one of these things happen: * the process exits * '_callCallback' or '_castCallback' return 'StopApiServer' If the process exist peacefully the parameter is 'Nothing', otherwise @Just "error message..."@ if the process exits with an error. The default behavior is defined in 'defaultTermination'."} -> ApiHandler api eff
+ Control.Eff.Concurrent: [ApiHandler] :: {_castCallback :: Maybe (Api api 'Asynchronous -> Eff eff ApiServerCmd) " A cast will not return a result directly. This is used for async methods. This returns an 'ApiServerCmd' to the server loop.", _callCallback :: forall reply. Maybe (Api api ( 'Synchronous reply) -> (reply -> Eff eff ()) -> Eff eff ApiServerCmd) " A call is a blocking operation, the caller is blocked until this handler calls the reply continuation. This returns an 'ApiServerCmd' to the server loop.", _terminateCallback :: Maybe (ExitReason 'Recoverable -> Eff eff ()) " This callback is called with @Nothing@ if one of these things happen: * the process exits * '_callCallback' or '_castCallback' return 'StopApiServer' If the process exist peacefully the parameter is 'NotServerCallbacking', otherwise @Just "error message..."@ if the process exits with an error. The default behavior is defined in 'defaultTermination'."} -> ApiHandler api eff
- Control.Eff.Concurrent: callCallback :: forall api_a18oA eff_a18oB reply_a18oE. Getter (ApiHandler api_a18oA eff_a18oB) (Maybe (Api api_a18oA ( 'Synchronous reply_a18oE) -> (reply_a18oE -> Eff eff_a18oB ()) -> Eff eff_a18oB ApiServerCmd))
+ Control.Eff.Concurrent: callCallback :: forall api_a1bk0 eff_a1bk1 reply_a1bk4. Getter (ApiHandler api_a1bk0 eff_a1bk1) (Maybe (Api api_a1bk0 ( 'Synchronous reply_a1bk4) -> (reply_a1bk4 -> Eff eff_a1bk1 ()) -> Eff eff_a1bk1 ApiServerCmd))
- Control.Eff.Concurrent: castCallback :: forall api_a18oA eff_a18oB. Lens' (ApiHandler api_a18oA eff_a18oB) (Maybe (Api api_a18oA 'Asynchronous -> Eff eff_a18oB ApiServerCmd))
+ Control.Eff.Concurrent: castCallback :: forall api_a1bk0 eff_a1bk1. Lens' (ApiHandler api_a1bk0 eff_a1bk1) (Maybe (Api api_a1bk0 'Asynchronous -> Eff eff_a1bk1 ApiServerCmd))
- Control.Eff.Concurrent: enqueueObservations :: forall o r q a. (SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO r, HasLogging IO q, Member Interrupts r, Lifted IO q, HasCallStack, MonadCatch (Eff r)) => SchedulerProxy q -> Server o -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
+ Control.Eff.Concurrent: enqueueObservations :: forall o r q a. (SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO r, HasLogging IO q, Member Interrupts r, Lifted IO q, HasCallStack) => SchedulerProxy q -> Server o -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
- Control.Eff.Concurrent: enqueueObservationsRegistered :: forall o r q a. (ServesApi o r q, SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO q, HasLogging IO r, Member Interrupts r, Lifted IO r, HasCallStack, MonadCatch (Eff r)) => SchedulerProxy q -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
+ Control.Eff.Concurrent: enqueueObservationsRegistered :: forall o r q a. (ServesApi o r q, SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO q, HasLogging IO r, Member Interrupts r, Lifted IO r, HasCallStack) => SchedulerProxy q -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
- Control.Eff.Concurrent: fromServer :: forall api_a17Kd api_a17Uv. Iso (Server api_a17Kd) (Server api_a17Uv) ProcessId ProcessId
+ Control.Eff.Concurrent: fromServer :: forall api_a17T7 api_a183p. Iso (Server api_a17T7) (Server api_a183p) ProcessId ProcessId
- Control.Eff.Concurrent: requestHandlerSelector :: forall eff_a18AQ. Lens' (ServerCallback eff_a18AQ) (MessageSelector (Eff eff_a18AQ ApiServerCmd))
+ Control.Eff.Concurrent: requestHandlerSelector :: forall eff_a1bwg. Lens' (ServerCallback eff_a1bwg) (MessageSelector (Eff eff_a1bwg ApiServerCmd))
- Control.Eff.Concurrent: terminateCallback :: forall api_a18oA eff_a18oB. Lens' (ApiHandler api_a18oA eff_a18oB) (Maybe (ExitReason 'Recoverable -> Eff eff_a18oB ()))
+ Control.Eff.Concurrent: terminateCallback :: forall api_a1bk0 eff_a1bk1. Lens' (ApiHandler api_a1bk0 eff_a1bk1) (Maybe (ExitReason 'Recoverable -> Eff eff_a1bk1 ()))
- Control.Eff.Concurrent: terminationHandler :: forall eff_a18AQ. Lens' (ServerCallback eff_a18AQ) (ExitReason 'Recoverable -> Eff eff_a18AQ ())
+ Control.Eff.Concurrent: terminationHandler :: forall eff_a1bwg. Lens' (ServerCallback eff_a1bwg) (ExitReason 'Recoverable -> Eff eff_a1bwg ())
- Control.Eff.Concurrent: toServerPids :: Servable a => proxy a -> ProcessId -> ServerPids a
+ Control.Eff.Concurrent: toServerPids :: ToServerPids t => proxy t -> ProcessId -> ServerPids t
- Control.Eff.Concurrent: type family ServerPids a;
+ Control.Eff.Concurrent: type family ServerPids t;
- Control.Eff.Concurrent.Api: fromServer :: forall api_a17Kd api_a17Uv. Iso (Server api_a17Kd) (Server api_a17Uv) ProcessId ProcessId
+ Control.Eff.Concurrent.Api: fromServer :: forall api_a17T7 api_a183p. Iso (Server api_a17T7) (Server api_a183p) ProcessId ProcessId
- Control.Eff.Concurrent.Api.Observer.Queue: enqueueObservations :: forall o r q a. (SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO r, HasLogging IO q, Member Interrupts r, Lifted IO q, HasCallStack, MonadCatch (Eff r)) => SchedulerProxy q -> Server o -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
+ Control.Eff.Concurrent.Api.Observer.Queue: enqueueObservations :: forall o r q a. (SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO r, HasLogging IO q, Member Interrupts r, Lifted IO q, HasCallStack) => SchedulerProxy q -> Server o -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
- Control.Eff.Concurrent.Api.Observer.Queue: enqueueObservationsRegistered :: forall o r q a. (ServesApi o r q, SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO q, HasLogging IO r, Member Interrupts r, Lifted IO r, HasCallStack, MonadCatch (Eff r)) => SchedulerProxy q -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
+ Control.Eff.Concurrent.Api.Observer.Queue: enqueueObservationsRegistered :: forall o r q a. (ServesApi o r q, SetMember Process (Process q) r, Typeable o, Show (Observation o), Observable o, HasLogging IO q, HasLogging IO r, Member Interrupts r, Lifted IO r, HasCallStack) => SchedulerProxy q -> Int -> Eff (ObservationQueueReader o : r) a -> Eff r a
- Control.Eff.Concurrent.Api.Server: [ApiHandler] :: {_castCallback :: Maybe (Api api 'Asynchronous -> Eff eff ApiServerCmd) " A cast will not return a result directly. This is used for async methods. This returns an 'ApiServerCmd' to the server loop.", _callCallback :: forall reply. Maybe (Api api ( 'Synchronous reply) -> (reply -> Eff eff ()) -> Eff eff ApiServerCmd) " A call is a blocking operation, the caller is blocked until this handler calls the reply continuation. This returns an 'ApiServerCmd' to the server loop.", _terminateCallback :: Maybe (ExitReason 'Recoverable -> Eff eff ()) " This callback is called with @Nothing@ if one of these things happen: * the process exits * '_callCallback' or '_castCallback' return 'StopApiServer' If the process exist peacefully the parameter is 'Nothing', otherwise @Just "error message..."@ if the process exits with an error. The default behavior is defined in 'defaultTermination'."} -> ApiHandler api eff
+ Control.Eff.Concurrent.Api.Server: [ApiHandler] :: {_castCallback :: Maybe (Api api 'Asynchronous -> Eff eff ApiServerCmd) " A cast will not return a result directly. This is used for async methods. This returns an 'ApiServerCmd' to the server loop.", _callCallback :: forall reply. Maybe (Api api ( 'Synchronous reply) -> (reply -> Eff eff ()) -> Eff eff ApiServerCmd) " A call is a blocking operation, the caller is blocked until this handler calls the reply continuation. This returns an 'ApiServerCmd' to the server loop.", _terminateCallback :: Maybe (ExitReason 'Recoverable -> Eff eff ()) " This callback is called with @Nothing@ if one of these things happen: * the process exits * '_callCallback' or '_castCallback' return 'StopApiServer' If the process exist peacefully the parameter is 'NotServerCallbacking', otherwise @Just "error message..."@ if the process exits with an error. The default behavior is defined in 'defaultTermination'."} -> ApiHandler api eff
- Control.Eff.Concurrent.Api.Server: callCallback :: forall api_a18oA eff_a18oB reply_a18oE. Getter (ApiHandler api_a18oA eff_a18oB) (Maybe (Api api_a18oA ( 'Synchronous reply_a18oE) -> (reply_a18oE -> Eff eff_a18oB ()) -> Eff eff_a18oB ApiServerCmd))
+ Control.Eff.Concurrent.Api.Server: callCallback :: forall api_a1bk0 eff_a1bk1 reply_a1bk4. Getter (ApiHandler api_a1bk0 eff_a1bk1) (Maybe (Api api_a1bk0 ( 'Synchronous reply_a1bk4) -> (reply_a1bk4 -> Eff eff_a1bk1 ()) -> Eff eff_a1bk1 ApiServerCmd))
- Control.Eff.Concurrent.Api.Server: castCallback :: forall api_a18oA eff_a18oB. Lens' (ApiHandler api_a18oA eff_a18oB) (Maybe (Api api_a18oA 'Asynchronous -> Eff eff_a18oB ApiServerCmd))
+ Control.Eff.Concurrent.Api.Server: castCallback :: forall api_a1bk0 eff_a1bk1. Lens' (ApiHandler api_a1bk0 eff_a1bk1) (Maybe (Api api_a1bk0 'Asynchronous -> Eff eff_a1bk1 ApiServerCmd))
- Control.Eff.Concurrent.Api.Server: requestHandlerSelector :: forall eff_a18AQ. Lens' (ServerCallback eff_a18AQ) (MessageSelector (Eff eff_a18AQ ApiServerCmd))
+ Control.Eff.Concurrent.Api.Server: requestHandlerSelector :: forall eff_a1bwg. Lens' (ServerCallback eff_a1bwg) (MessageSelector (Eff eff_a1bwg ApiServerCmd))
- Control.Eff.Concurrent.Api.Server: terminateCallback :: forall api_a18oA eff_a18oB. Lens' (ApiHandler api_a18oA eff_a18oB) (Maybe (ExitReason 'Recoverable -> Eff eff_a18oB ()))
+ Control.Eff.Concurrent.Api.Server: terminateCallback :: forall api_a1bk0 eff_a1bk1. Lens' (ApiHandler api_a1bk0 eff_a1bk1) (Maybe (ExitReason 'Recoverable -> Eff eff_a1bk1 ()))
- Control.Eff.Concurrent.Api.Server: terminationHandler :: forall eff_a18AQ. Lens' (ServerCallback eff_a18AQ) (ExitReason 'Recoverable -> Eff eff_a18AQ ())
+ Control.Eff.Concurrent.Api.Server: terminationHandler :: forall eff_a1bwg. Lens' (ServerCallback eff_a1bwg) (ExitReason 'Recoverable -> Eff eff_a1bwg ())

Files

ChangeLog.md view
@@ -1,5 +1,16 @@ # Changelog for extensible-effects-concurrent +## 0.13.2++- Add `ProcessFinished`+- Add `tryUninterrupted`+- Add simpler `Server2`++## 0.13.1++- Remove misguided `MonadCatch` constraints in the `ObservationQueueReader`+    functions, and use `Interrupts` instead+ ## 0.13.0  - Fix bad constraints in `Queue` observer
README.md view
@@ -34,21 +34,25 @@     -- The SchedulerProxy paremeter contains the effects of a specific scheduler     -- implementation. -newtype WhoAreYou = WhoAreYou ProcessId deriving (Typeable, NFData) -firstExample :: (HasLoggingIO q) => SchedulerProxy q -> Eff (Process q ': q) ()+newtype WhoAreYou = WhoAreYou ProcessId deriving (Typeable, NFData, Show)++firstExample+  :: (HasLogging IO q) => SchedulerProxy q -> Eff (InterruptableProcess q) () firstExample px = do   person <- spawn     (do       logInfo "I am waiting for someone to ask me..."       WhoAreYou replyPid <- receiveMessage px-      sendMessageAs px replyPid "Alice"+      sendMessage px replyPid "Alice"       logInfo (show replyPid ++ " just needed to know it.")     )   me <- self px-  sendMessageAs px person (WhoAreYou me)+  sendMessage px person (WhoAreYou me)   personName <- receiveMessage px   logInfo ("I just met " ++ personName)++ ```  **Running** this example causes this output:
examples/example-4/Main.hs view
@@ -5,7 +5,6 @@ import           Control.Eff.Concurrent import           Data.Dynamic import           Control.Concurrent-import           Control.Applicative import           Control.DeepSeq  main :: IO ()@@ -34,13 +33,3 @@   sendMessage px person (WhoAreYou me)   personName <- receiveMessage px   logInfo ("I just met " ++ personName)---selectInt :: MessageSelector Int-selectInt = selectMessage--selectString :: MessageSelector String-selectString = selectMessage--selectIntOrString :: MessageSelector (Either Int String)-selectIntOrString = Left <$> selectInt <|> Right <$> selectString
extensible-effects-concurrent.cabal view
@@ -1,5 +1,5 @@ name:           extensible-effects-concurrent-version:        0.13.0+version:        0.13.2 description:    Please see the README on GitHub at <https://github.com/sheyll/extensible-effects-concurrent#readme> synopsis:       Message passing concurrency as extensible-effect homepage:       https://github.com/sheyll/extensible-effects-concurrent#readme@@ -63,6 +63,7 @@                   Control.Eff.Concurrent,                   Control.Eff.Concurrent.Api,                   Control.Eff.Concurrent.Api.Client,+                  Control.Eff.Concurrent.Api.Server2,                   Control.Eff.Concurrent.Api.Server,                   Control.Eff.Concurrent.Process,                   Control.Eff.Concurrent.Process.Timer,@@ -224,7 +225,7 @@   ghc-options: -Wall -threaded -fno-full-laziness -rtsopts -with-rtsopts=-N   build-depends:                 async-              , base >=4.7 && <4.12+              , base >=4.7 && <5               , data-default               , extensible-effects-concurrent               , extensible-effects >= 3.1.0.2 && < 3.2
src/Control/Eff/Concurrent.hs view
@@ -17,6 +17,9 @@     -- ** /Server/ Functions for Providing APIs     module Control.Eff.Concurrent.Api.Server   ,+    -- ** /Server/ Functions for Providing APIs (new experimental)+    module Control.Eff.Concurrent.Api.Server2+  ,     -- ** /Observer/ Functions for Events and Event Listener     module Control.Eff.Concurrent.Api.Observer   ,@@ -99,6 +102,7 @@                                                 , receiveWithMonitor                                                 , provideInterruptsShutdown                                                 , handleInterrupts+                                                , tryUninterrupted                                                 , exitOnInterrupt                                                 , logInterrupts                                                 , provideInterrupts@@ -151,6 +155,29 @@                                                 , whereIsServer                                                 , ServerReader                                                 )+import           Control.Eff.Concurrent.Api.Server2+                                                ( spawnApiServer+                                                , spawnApiServerStateful+                                                , spawnApiServerEffectful+                                                , CallbackResult(..)+                                                , MessageCallback(..)+                                                , handleCasts+                                                , handleCalls+                                                , handleCastsAndCalls+                                                , handleMessages+                                                , handleSelectedMessages+                                                , handleAnyMessages+                                                , handleProcessDowns+                                                , dropUnhandledMessages+                                                , exitOnUnhandled+                                                , logUnhandledMessages+                                                , (^:)+                                                , fallbackHandler+                                                , ToServerPids(..)+                                                , InterruptCallback(..)+                                                , stopServerOnInterrupt+                                                )+ import           Control.Eff.Concurrent.Api.Server                                                 ( serve                                                 , spawnServer@@ -171,7 +198,7 @@                                                 , unhandledCallError                                                 , unhandledCastError                                                 , defaultTermination-                                                , Servable(..)+                                                -- , Servable(..)                                                 , ServerCallback(..)                                                 , requestHandlerSelector                                                 , terminationHandler
src/Control/Eff/Concurrent/Api/Observer/Queue.hs view
@@ -102,7 +102,6 @@      , Member Interrupts r      , Lifted IO r      , HasCallStack-     , MonadCatch (Eff r)      )   => SchedulerProxy q   -> Int@@ -129,7 +128,6 @@      , Member Interrupts r      , Lifted IO q      , HasCallStack-     , MonadCatch (Eff r)      )   => SchedulerProxy q   -> Server o@@ -171,15 +169,16 @@      , Typeable a      , Show (Observation a)      , HasLogging IO e-     , MonadCatch (Eff e)      , Integral len+     , Member Interrupts e      )   => len   -> Eff (ObservationQueueReader a ': e) b   -> Eff e b withQueue queueLimit e = do-  q    <- liftIO (newTBQueueIO (fromIntegral queueLimit))-  res  <- Safe.tryAny (runReader (ObservationQueue q) e)+  q   <- liftIO (newTBQueueIO (fromIntegral queueLimit))+  res <- handleInterrupts (return . Left)+                          (Right <$> runReader (ObservationQueue q) e)   rest <- liftIO (atomically (flushTBQueue q))   unless     (null rest)
src/Control/Eff/Concurrent/Api/Server.hs view
@@ -50,6 +50,7 @@ import           Control.DeepSeq import           Data.Default + -- | A record of callbacks, handling requests sent to a /server/ 'Process', all -- belonging to a specific 'Api' family instance. -- The values of this type can be 'serve'ed or combined via 'Servable' or@@ -70,7 +71,7 @@      --  * the process exits      --  * '_callCallback' or '_castCallback' return 'StopApiServer'      ---     -- If the process exist peacefully the parameter is 'Nothing',+     -- If the process exist peacefully the parameter is 'NotServerCallbacking',      -- otherwise @Just "error message..."@ if the process exits with an      -- error.      --
+ src/Control/Eff/Concurrent/Api/Server2.hs view
@@ -0,0 +1,363 @@+-- | Experimental new 'Api' server handler.+--+-- @since 0.13.2+module Control.Eff.Concurrent.Api.Server2+  ( -- * Starting Api Servers+    spawnApiServer+  , spawnApiServerStateful+  , spawnApiServerEffectful+  -- ** Api Server Callbacks+  , CallbackResult(..)+  , MessageCallback(..)+  -- ** Callback Smart Contructors+  -- *** Calls and Casts (for 'Api's)+  , handleCasts+  , handleCalls+  , handleCastsAndCalls+  -- *** Generic Message Handler+  , handleMessages+  , handleSelectedMessages+  , handleAnyMessages+  , handleProcessDowns+  -- *** Fallback Handler+  , dropUnhandledMessages+  , exitOnUnhandled+  , logUnhandledMessages+  -- ** Api Composition+  , (^:)+  , fallbackHandler+  , ToServerPids(..)+  -- ** Interrupt handler+  , InterruptCallback(..)+  , stopServerOnInterrupt+  )+where++import           Control.Eff+import           Control.Eff.Extend+import           Control.Eff.Log+import           Control.Eff.State.Lazy+import           Control.Eff.Concurrent.Api+import           Control.Eff.Concurrent.Process+import           Control.Monad                  ( (>=>) )+import           Data.Proxy+import           Data.Dynamic+import           Control.Applicative+import           GHC.Stack+import           GHC.Generics+import           Control.DeepSeq+import           Data.Kind+import           Data.Default++-- | /Server/ an 'Api' in a newly spawned process.+--+-- @since 0.13.2+spawnApiServer+  :: forall api eff+   . (ToServerPids api, HasCallStack)+  => MessageCallback api (InterruptableProcess eff)+  -> InterruptCallback (ConsProcess eff)+  -> Eff (InterruptableProcess eff) (ServerPids api)+spawnApiServer (MessageCallback sel cb) (InterruptCallback intCb) =+  toServerPids (Proxy @api)+    <$> (spawnRaw $ receiveSelectedLoop+          (SP @eff)+          sel+          (   either (fmap Left . intCb) (fmap Right . provideInterrupts . cb)+          >=> handleCallbackResult+          )+        )+ where+  handleCallbackResult+    :: Either CallbackResult (Either InterruptReason CallbackResult)+    -> Eff (ConsProcess eff) (Maybe ())+  handleCallbackResult (Left HandleNext) = return Nothing+  handleCallbackResult (Left (StopServer r)) = exitBecause SP (NotRecovered r)+  handleCallbackResult (Right (Right HandleNext)) = return Nothing+  handleCallbackResult (Right (Right (StopServer r))) =+    intCb r >>= handleCallbackResult . Left+  handleCallbackResult (Right (Left r)) =+    intCb r >>= handleCallbackResult . Left++-- | /Server/ an 'Api' in a newly spawned process; the callbacks have access+-- to some state initialed by the function in the first parameter.+--+-- @since 0.13.2+spawnApiServerStateful+  :: forall api eff state+   . (HasCallStack)+  => Eff (InterruptableProcess eff) state+  -> MessageCallback api (State state ': InterruptableProcess eff)+  -> InterruptCallback (State state ': ConsProcess eff)+  -> Eff (InterruptableProcess eff) (Server api)+spawnApiServerStateful initEffect (MessageCallback sel cb) (InterruptCallback intCb)+  = fmap asServer $ spawnRaw $ do+    state <- provideInterruptsShutdown initEffect+    evalState state $ receiveSelectedLoop (SP @eff) sel $ \msg -> case msg of+      Left  m -> invokeIntCb m+      Right m -> do+        s <- get+        r <- raise (provideInterrupts (evalState s (cb m)))+        case r of+          Left  i              -> invokeIntCb i+          Right (StopServer i) -> invokeIntCb i+          Right HandleNext     -> return Nothing+ where+  invokeIntCb j = do+    l <- intCb j+    case l of+      HandleNext                 -> return Nothing+      StopServer ProcessFinished -> return (Just ())+      StopServer k               -> exitBecause SP (NotRecovered k)++-- | /Server/ an 'Api' in a newly spawned process; The caller provides an+-- effect handler for arbitrary effects used by the server callbacks.+--+-- @since 0.13.2+spawnApiServerEffectful+  :: forall api eff serverEff+   . ( HasCallStack+     , Member Interrupts serverEff+     , SetMember Process (Process eff) serverEff+     )+  => (forall b . Eff serverEff b -> Eff (InterruptableProcess eff) b)+  -> MessageCallback api serverEff+  -> InterruptCallback serverEff+  -> Eff (InterruptableProcess eff) (Server api)+spawnApiServerEffectful handleServerInteralEffects scb (InterruptCallback intCb)+  = asServer <$> (spawn (handleServerInteralEffects (go scb)))+ where+  go (MessageCallback sel cb) = receiveSelectedLoop+    (SP @eff)+    sel+    (   either (fmap Left . intCb) (fmap Right . tryUninterrupted . cb)+    >=> handleCallbackResult+    )+   where+    handleCallbackResult+      :: Either CallbackResult (Either InterruptReason CallbackResult)+      -> Eff serverEff (Maybe ())+    handleCallbackResult (Left HandleNext) = return Nothing+    handleCallbackResult (Left (StopServer r)) =+      exitBecause SP (NotRecovered r)+    handleCallbackResult (Right (Right HandleNext)) = return Nothing+    handleCallbackResult (Right (Right (StopServer r))) =+      intCb r >>= handleCallbackResult . Left+    handleCallbackResult (Right (Left r)) =+      intCb r >>= handleCallbackResult . Left++-- | A command to the server loop started e.g. by 'server' or 'spawnServerWithEffects'.+-- Typically returned by an 'ApiHandler' member to indicate if the server+-- should continue or stop.+--+-- @since 0.13.2+data CallbackResult where+  -- | Tell the server to keep the server loop running+  HandleNext :: CallbackResult+  -- | Tell the server to exit, this will make 'serve' stop handling requests without+  -- exitting the process. '_terminateCallback' will be invoked with the given+  -- optional reason.+  StopServer :: InterruptReason -> CallbackResult+  --  SendReply :: reply -> CallbackResult () -> CallbackResult (reply -> Eff eff ())+  deriving (Show, Typeable, Generic)++instance NFData CallbackResult++-- | An existential wrapper around  a 'MessageSelector' and a function that+-- handles the selected message. The @api@ type parameter is a phantom type.+--+-- The return value if the handler function is a 'CallbackResult'.+--+-- @since 0.13.2+data MessageCallback api eff where+   MessageCallback :: MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback api eff++instance Semigroup (MessageCallback api eff) where+ (MessageCallback selL runL) <> (MessageCallback selR runR) =+    MessageCallback (Left <$> selL <|> Right <$> selR) (either runL runR)++instance Monoid (MessageCallback api eff) where+  mappend = (<>)+  mempty = MessageCallback selectAnyMessageLazy (const (pure HandleNext))++instance Default (MessageCallback api eff) where+  def = mempty++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleMessages+  :: forall eff a+   . (HasCallStack, NFData a, Typeable a)+  => (a -> Eff eff CallbackResult)+  -> MessageCallback '[] eff+handleMessages = MessageCallback selectMessage++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleSelectedMessages+  :: forall eff a+   . HasCallStack+  => MessageSelector a+  -> (a -> Eff eff CallbackResult)+  -> MessageCallback '[] eff+handleSelectedMessages = MessageCallback++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleAnyMessages+  :: forall eff+   . HasCallStack+  => (Dynamic -> Eff eff CallbackResult)+  -> MessageCallback '[] eff+handleAnyMessages = MessageCallback selectAnyMessageLazy++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleCasts+  :: forall api eff+   . ( HasCallStack+     , NFData (Api api 'Asynchronous)+     , Typeable (Api api 'Asynchronous)+     )+  => (Api api 'Asynchronous -> Eff eff CallbackResult)+  -> MessageCallback api eff+handleCasts = MessageCallback selectMessage++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleCalls+  :: forall api eff reply+   . ( HasCallStack+     , NFData (Api api ( 'Synchronous reply))+     , Typeable (Api api ( 'Synchronous reply))+     )+  => (Api api ( 'Synchronous reply) -> Eff eff CallbackResult)+  -> MessageCallback api eff+handleCalls = MessageCallback selectMessage++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleCastsAndCalls+  :: forall api eff reply+   . ( HasCallStack+     , NFData (Api api ( 'Synchronous reply))+     , Typeable (Api api ( 'Synchronous reply))+     , NFData (Api api 'Asynchronous)+     , Typeable (Api api 'Asynchronous)+     )+  => (Api api 'Asynchronous -> Eff eff CallbackResult)+  -> (Api api ( 'Synchronous reply) -> Eff eff CallbackResult)+  -> MessageCallback api eff+handleCastsAndCalls onCast onCall = handleCalls onCall <> handleCasts onCast++-- | A smart constructor for 'MessageCallback's+--+-- @since 0.13.2+handleProcessDowns+  :: forall eff+   . HasCallStack+  => (MonitorReference -> Eff eff CallbackResult)+  -> MessageCallback '[] eff+handleProcessDowns k = MessageCallback selectMessage (k . downReference)++-- | Compose two 'Api's to a type-leve pair of them.+--+-- > handleCalls api1calls ^: handleCalls api2calls ^:+--+-- @since 0.13.2+(^:)+  :: forall (api1 :: Type) (apis2 :: [Type]) eff+   . HasCallStack+  => MessageCallback api1 eff+  -> MessageCallback apis2 eff+  -> MessageCallback (api1 ': apis2) eff+(MessageCallback selL runL) ^: (MessageCallback selR runR) =+  MessageCallback (Left <$> selL <|> Right <$> selR) (either runL runR)++infixr 5 ^:++-- | Make a fallback handler, i.e. a handler to which no other can be composed+-- to from the right.+--+-- @since 0.13.2+fallbackHandler+  :: forall api eff+   . HasCallStack+  => MessageCallback api eff+  -> MessageCallback '[] eff+fallbackHandler (MessageCallback s r) = MessageCallback s r++-- | A 'fallbackHandler' that drops the left-over messages.+--+-- @since 0.13.2+dropUnhandledMessages :: forall eff . HasCallStack => MessageCallback '[] eff+dropUnhandledMessages =+  MessageCallback selectAnyMessageLazy (const (return HandleNext))++-- | A 'fallbackHandler' that terminates if there are unhandled messages.+--+-- @since 0.13.2+exitOnUnhandled :: forall eff . HasCallStack => MessageCallback '[] eff+exitOnUnhandled = MessageCallback selectAnyMessageLazy $ \msg ->+  return (StopServer (ProcessError ("unhandled message " ++ show msg)))++-- | A 'fallbackHandler' that drops the left-over messages.+--+-- @since 0.13.2+logUnhandledMessages+  :: forall eff+   . (Member (Logs LogMessage) eff, HasCallStack)+  => MessageCallback '[] eff+logUnhandledMessages = MessageCallback selectAnyMessageLazy $ \msg -> do+  logWarning ("ignoring unhandled message " ++ show msg)+  return HandleNext++-- | Helper type class for the return values of 'spawnApiServer' et al.+--+-- @since 0.13.2+class ToServerPids (t :: k) where+  type ServerPids t+  toServerPids :: proxy t -> ProcessId -> ServerPids t++instance ToServerPids '[] where+  type ServerPids '[] = ProcessId+  toServerPids _ = id++instance+  forall (api1 :: Type) (api2 :: [Type])+  . (ToServerPids api1, ToServerPids api2)+  => ToServerPids (api1 ': api2) where+  type ServerPids (api1 ': api2) = (ServerPids api1, ServerPids api2)+  toServerPids _ p =+    (toServerPids (Proxy @api1) p, toServerPids (Proxy @api2) p)++instance+  forall (api1 :: Type)+  . (ToServerPids api1)+  => ToServerPids api1 where+  type ServerPids api1 = Server api1+  toServerPids _ = asServer++-- | Just a wrapper around a function that will be applied to the result of+-- a 'MessageCallback's 'StopServer' clause, or an 'InterruptReason' caught during+-- the execution of @receive@ or a 'MessageCallback'+--+-- @since 0.13.2+data InterruptCallback eff where+   InterruptCallback ::+     (InterruptReason -> Eff eff CallbackResult) -> InterruptCallback eff++instance Default (InterruptCallback eff) where+  def = stopServerOnInterrupt++-- | A smart constructor for 'InterruptCallback's+--+-- @since 0.13.2+stopServerOnInterrupt :: forall eff . HasCallStack => InterruptCallback eff+stopServerOnInterrupt = InterruptCallback (pure . StopServer)
src/Control/Eff/Concurrent/Process.hs view
@@ -86,6 +86,7 @@   -- ** Process Interrupt Handling   , provideInterruptsShutdown   , handleInterrupts+  , tryUninterrupted   , exitOnInterrupt   , logInterrupts   , provideInterrupts@@ -470,6 +471,7 @@ -- | Get the 'ExitRecover'y toExitRecovery :: ExitReason r -> ExitRecovery toExitRecovery = \case+  ProcessFinished           -> Recoverable   (ProcessNotRunning    _)  -> Recoverable   (LinkedProcessCrashed _)  -> Recoverable   (ProcessError         _)  -> Recoverable@@ -495,12 +497,21 @@ -- | Get the 'ExitSeverity' of a 'ExitReason'. toExitSeverity :: ExitReason e -> ExitSeverity toExitSeverity = \case-  ExitNormally -> NormalExit-  _            -> Crash+  ExitNormally    -> NormalExit+  ProcessFinished -> NormalExit+  _               -> Crash  -- | A sum-type with reasons for why a process exists the scheduling loop, -- this includes errors, that can occur when scheduleing messages. data ExitReason (t :: ExitRecovery) where+    -- | A process has finished a unit of work and might exit or work on+    --   something else. This is primarily used for interupting infinite+    --   server loops, allowing for additional cleanup work before+    --   exitting (e.g. with 'ExitNormally')+    --+    -- @since 0.13.2+    ProcessFinished+      :: ExitReason 'Recoverable     -- | A process that should be running was not running.     ProcessNotRunning       :: ProcessId -> ExitReason 'Recoverable@@ -529,6 +540,7 @@   showsPrec d =     showParen (d>=10) .     (\case+        ProcessFinished             -> showString "process finished"         ProcessNotRunning p         -> showString "process not running: " . shows p         LinkedProcessCrashed m      -> showString "linked process "                                         . shows m . showString " crashed"@@ -546,6 +558,7 @@ instance Exc.Exception (ExitReason 'NoRecovery )  instance NFData (ExitReason x) where+  rnf ProcessFinished = rnf ()   rnf (ProcessNotRunning !l) = rnf l   rnf (LinkedProcessCrashed !l) = rnf l   rnf (ProcessError !l) = rnf l@@ -555,6 +568,9 @@   rnf Killed = rnf ()  instance Ord (ExitReason x) where+  compare ProcessFinished ProcessFinished = EQ+  compare ProcessFinished _ = LT+  compare _ ProcessFinished = GT   compare (ProcessNotRunning l) (ProcessNotRunning r) = compare l r   compare (ProcessNotRunning _) _ = LT   compare _ (ProcessNotRunning _) = GT@@ -575,6 +591,7 @@   compare Killed Killed = EQ  instance Eq (ExitReason x) where+  (==) ProcessFinished ProcessFinished = True   (==) (ProcessNotRunning l) (ProcessNotRunning r) = (==) l r   (==) ExitNormally ExitNormally = True   (==) (LinkedProcessCrashed l) (LinkedProcessCrashed r) = l == r@@ -588,6 +605,7 @@ -- | A predicate for linked process __crashes__. isBecauseDown :: Maybe ProcessId -> ExitReason r -> Bool isBecauseDown mp = \case+  ProcessFinished         -> False   ProcessNotRunning    _  -> False   LinkedProcessCrashed p  -> maybe True (== p) mp   ProcessError         _  -> False@@ -626,6 +644,16 @@   -> Eff r a handleInterrupts = flip catchError +-- | Like 'handleInterrupts', but instead of passing the 'InterruptReason'+-- to a handler function, 'Either' is returned.+--+-- @since 0.13.2+tryUninterrupted+  :: (HasCallStack, Member Interrupts r)+  => Eff r a+  -> Eff r (Either InterruptReason a)+tryUninterrupted = handleInterrupts (pure . Left) . fmap Right+ -- | Handle interrupts by logging them with `logProcessExit` and otherwise -- ignoring them. logInterrupts@@ -697,6 +725,7 @@ fromSomeExitReason   :: SomeExitReason -> Either (ExitReason 'NoRecovery) InterruptReason fromSomeExitReason (SomeExitReason e) = case e of+  recoverable@ProcessFinished          -> Right recoverable   recoverable@(ProcessNotRunning    _) -> Right recoverable   recoverable@(LinkedProcessCrashed _) -> Right recoverable   recoverable@(ProcessError         _) -> Right recoverable
test/Common.hs view
@@ -30,7 +30,7 @@ withTestLogC doSchedule k = k   (return     (\e -> withAsyncLogChannel-      1000+      (1000 :: Integer)       (multiMessageLogWriter         (\writeWith ->           writeWith
test/ForkIOScheduler.hs view
@@ -12,11 +12,14 @@ import           Control.Eff.Concurrent.Process.Timer import           Control.Eff.Concurrent.Process.ForkIOScheduler                                                as Scheduler-import           Control.Monad                  ( void, replicateM_ )+import           Control.Monad                  ( void+                                                , replicateM_+                                                ) import           Test.Tasty import           Test.Tasty.HUnit import           Data.Dynamic import           Common+import           Numeric.Natural import           Data.Default  test_IOExceptionsIsolated :: TestTree@@ -31,7 +34,7 @@       $ do           aVar <- newEmptyTMVarIO           withAsyncLogChannel-            1000+            (1000 :: Natural)             def -- (singleMessageLogWriter (putStrLn . renderLogMessage))             (Scheduler.defaultMainWithLogChannel               (do@@ -99,7 +102,7 @@   (testCase     "spawn a child and return"     (withAsyncLogChannel-      1000+      (1000 :: Natural)       def       (Scheduler.defaultMainWithLogChannel         (void (spawn (void (receiveAnyMessage forkIoScheduler))))@@ -112,7 +115,7 @@   (testCase     "spawn a child and exit normally"     (withAsyncLogChannel-      1000+      (1000 :: Natural)       def       (Scheduler.defaultMainWithLogChannel         (do@@ -131,7 +134,7 @@     (testCase       "spawn a child with a busy send loop and exit normally"       (withAsyncLogChannel-        1000+        (1000 :: Natural)         def         (Scheduler.defaultMainWithLogChannel           (do@@ -152,7 +155,7 @@   (testCase     "spawn a child and let it return and return"     (withAsyncLogChannel-      1000+      (1000 :: Natural)       def       (Scheduler.defaultMainWithLogChannel         (do@@ -169,7 +172,7 @@   (testCase     "spawn a child and let it exit and exit"     (withAsyncLogChannel-      1000+      (1000 :: Natural)       def       (Scheduler.defaultMainWithLogChannel         (do@@ -192,7 +195,7 @@ test_timer =   setTravisTestOptions     $ testCase "flush via timer"-    $ withAsyncLogChannel 1000 def+    $ withAsyncLogChannel (1000 :: Natural) def     $ Scheduler.defaultMainWithLogChannel     $ do         let n = 100
test/ProcessBehaviourTestCases.hs view
@@ -172,12 +172,14 @@         let px = SP         me <- self px         spawn_-          $ replicateM_ 10 (sendMessage px me True) >> sendMessage px me ()-        spawn_ $ replicateM_-          10-          (sendMessage px me (123.23411 :: Float)) >> sendMessage px me ()+          $  replicateM_ 10 (sendMessage px me True)+          >> sendMessage px me ()         spawn_-          $ replicateM_ 10 (sendMessage px me "123") >> sendMessage px me ()+          $  replicateM_ 10 (sendMessage px me (123.23411 :: Float))+          >> sendMessage px me ()+        spawn_+          $  replicateM_ 10 (sendMessage px me "123")+          >> sendMessage px me ()         ()   <- receiveMessage px         ()   <- receiveMessage px         ()   <- receiveMessage px@@ -863,16 +865,18 @@         foo1 = void (receiveAnyMessage SP)         foo2 foo1Pid = do           linkProcess SP foo1Pid-          ("unlink foo1", barPid) <- receiveMessage SP+          (r1, barPid) <- receiveMessage SP+          lift ("unlink foo1" @=? r1)           unlinkProcess SP foo1Pid           sendMessage SP barPid ("unlinked foo1", foo1Pid)-          "the end" <- receiveMessage SP+          receiveMessage SP >>= lift . (@?= "the end")           exitWithError SP "foo two"         bar foo2Pid parentPid = do           linkProcess SP foo2Pid           me <- self SP           sendMessage SP foo2Pid ("unlink foo1", me)-          ("unlinked foo1", foo1Pid) <- receiveMessage SP+          (r1, foo1Pid) <- receiveMessage SP+          lift ("unlinked foo1" @=? r1)           handleInterrupts             (const (return ()))             (do@@ -993,7 +997,8 @@         me    <- self SP         other <- spawn           (do-            () <- receiveMessage @() SP+            r <- receiveMessage @() SP+            lift (r @?= ())             sendMessage SP me (123 :: Int)           )         pd1 <- receiveAfter @() SP 10000@@ -1012,7 +1017,8 @@         other <- spawn           (do             replicateM_ n $ sendMessage SP me "bad message"-            () <- receiveMessage @() SP+            r <- receiveMessage @() SP+            lift (r @?= ())             replicateM_ n $ sendMessage SP me testMsg           )         receiveAfter @Float SP 100 >>= lift . (@?= Nothing)