Safe Haskell | None |
---|---|
Language | Haskell2010 |
Erlang style processes with message passing concurrency based on
(more) extensible-effects
.
Synopsis
- newtype ProcessId = ProcessId {}
- data ProcessDown = ProcessDown {}
- data MonitorReference = MonitorReference {}
- data SomeExitReason where
- SomeExitReason :: ExitReason x -> SomeExitReason
- type InterruptableProcess e = Interrupts ': ConsProcess e
- type Interrupts = Exc InterruptReason
- type InterruptReason = ExitReason Recoverable
- data ExitReason (t :: ExitRecovery) where
- ProcessFinished :: ExitReason Recoverable
- ProcessNotRunning :: ProcessId -> ExitReason Recoverable
- ProcessTimeout :: String -> ExitReason Recoverable
- LinkedProcessCrashed :: ProcessId -> ExitReason Recoverable
- ProcessError :: String -> ExitReason Recoverable
- ExitNormally :: ExitReason NoRecovery
- NotRecovered :: ExitReason Recoverable -> ExitReason NoRecovery
- UnexpectedException :: String -> String -> ExitReason NoRecovery
- Killed :: ExitReason NoRecovery
- data ExitSeverity
- = NormalExit
- | Crash
- data ExitRecovery
- data ProcessState
- type ConsProcess r = Process r ': r
- data MessageSelector a
- data ResumeProcess v where
- Interrupted :: InterruptReason -> ResumeProcess v
- ResumeWith :: a -> ResumeProcess a
- data StrictDynamic
- data Process (r :: [Type -> Type]) b where
- FlushMessages :: Process r (ResumeProcess [StrictDynamic])
- YieldProcess :: Process r (ResumeProcess ())
- SelfPid :: Process r (ResumeProcess ProcessId)
- Spawn :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId)
- SpawnLink :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId)
- GetProcessState :: ProcessId -> Process r (ResumeProcess (Maybe ProcessState))
- Shutdown :: ExitReason NoRecovery -> Process r a
- SendShutdown :: ProcessId -> ExitReason NoRecovery -> Process r (ResumeProcess ())
- SendInterrupt :: ProcessId -> InterruptReason -> Process r (ResumeProcess ())
- SendMessage :: ProcessId -> StrictDynamic -> Process r (ResumeProcess ())
- ReceiveSelectedMessage :: forall r a. MessageSelector a -> Process r (ResumeProcess a)
- MakeReference :: Process r (ResumeProcess Int)
- Monitor :: ProcessId -> Process r (ResumeProcess MonitorReference)
- Demonitor :: MonitorReference -> Process r (ResumeProcess ())
- Link :: ProcessId -> Process r (ResumeProcess ())
- Unlink :: ProcessId -> Process r (ResumeProcess ())
- toStrictDynamic :: (Typeable a, NFData a) => a -> StrictDynamic
- fromStrictDynamic :: Typeable a => StrictDynamic -> Maybe a
- unwrapStrictDynamic :: StrictDynamic -> Dynamic
- selectMessage :: Typeable t => MessageSelector t
- filterMessage :: Typeable a => (a -> Bool) -> MessageSelector a
- selectMessageWith :: Typeable a => (a -> Maybe b) -> MessageSelector b
- selectDynamicMessage :: (StrictDynamic -> Maybe a) -> MessageSelector a
- selectAnyMessage :: MessageSelector StrictDynamic
- toExitRecovery :: ExitReason r -> ExitRecovery
- toExitSeverity :: ExitReason e -> ExitSeverity
- isBecauseDown :: Maybe ProcessId -> ExitReason r -> Bool
- provideInterruptsShutdown :: forall e a. Eff (InterruptableProcess e) a -> Eff (ConsProcess e) a
- handleInterrupts :: (HasCallStack, Member Interrupts r) => (InterruptReason -> Eff r a) -> Eff r a -> Eff r a
- tryUninterrupted :: (HasCallStack, Member Interrupts r) => Eff r a -> Eff r (Either InterruptReason a)
- logInterrupts :: forall r. (Member Logs r, HasCallStack, Member Interrupts r) => Eff r () -> Eff r ()
- exitOnInterrupt :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r) => Eff r a -> Eff r a
- provideInterrupts :: HasCallStack => Eff (Interrupts ': r) a -> Eff r (Either InterruptReason a)
- mergeEitherInterruptAndExitReason :: Either InterruptReason (ExitReason NoRecovery) -> ExitReason NoRecovery
- interrupt :: (HasCallStack, Member Interrupts r) => InterruptReason -> Eff r a
- isCrash :: ExitReason x -> Bool
- isRecoverable :: ExitReason x -> Bool
- fromSomeExitReason :: SomeExitReason -> Either (ExitReason NoRecovery) InterruptReason
- toCrashReason :: ExitReason x -> Maybe Text
- logProcessExit :: forall e x. (Member Logs e, HasCallStack) => ExitReason x -> Eff e ()
- executeAndResume :: forall q r v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r (Either (ExitReason Recoverable) v)
- executeAndResumeOrExit :: forall r q v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r v
- executeAndResumeOrThrow :: forall q r v. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => Process q (ResumeProcess v) -> Eff r v
- yieldProcess :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => Eff r ()
- sendMessage :: forall r q o. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o, NFData o) => ProcessId -> o -> Eff r ()
- sendAnyMessage :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => ProcessId -> StrictDynamic -> Eff r ()
- sendShutdown :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => ProcessId -> ExitReason NoRecovery -> Eff r ()
- sendInterrupt :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => ProcessId -> InterruptReason -> Eff r ()
- spawn :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId
- spawn_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ()
- spawnLink :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId
- spawnRaw :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r ProcessId
- spawnRaw_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r ()
- isProcessAlive :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r Bool
- receiveAnyMessage :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff r StrictDynamic
- receiveSelectedMessage :: forall r q a. (HasCallStack, Show a, SetMember Process (Process q) r, Member Interrupts r) => MessageSelector a -> Eff r a
- receiveMessage :: forall a r q. (HasCallStack, Typeable a, NFData a, Show a, SetMember Process (Process q) r, Member Interrupts r) => Eff r a
- flushMessages :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff r [StrictDynamic]
- receiveSelectedLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => MessageSelector a -> (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult
- receiveAnyLoop :: forall r q endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => (Either InterruptReason StrictDynamic -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult
- receiveLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack, NFData a, Typeable a) => (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult
- self :: (HasCallStack, SetMember Process (Process q) r) => Eff r ProcessId
- makeReference :: (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff r Int
- monitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r MonitorReference
- demonitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => MonitorReference -> Eff r ()
- withMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> (MonitorReference -> Eff r a) -> Eff r a
- receiveWithMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r, Typeable a, Show a) => ProcessId -> MessageSelector a -> Eff r (Either ProcessDown a)
- becauseProcessIsDown :: ProcessDown -> InterruptReason
- selectProcessDown :: MonitorReference -> MessageSelector ProcessDown
- linkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r ()
- unlinkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r ()
- exitBecause :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => ExitReason NoRecovery -> Eff r a
- exitNormally :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => Eff r a
- exitWithError :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => String -> Eff r a
- fromProcessId :: Iso' ProcessId Int
- data TimerElapsed
- data TimerReference
- data Timeout
- receiveAfter :: forall a r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Typeable a, NFData a, Show a) => Timeout -> Eff r (Maybe a)
- receiveSelectedAfter :: forall a r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Show a) => MessageSelector a -> Timeout -> Eff r (Either TimerElapsed a)
- receiveSelectedWithMonitorAfter :: forall a r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Show a) => ProcessId -> MessageSelector a -> Timeout -> Eff r (Either (Either ProcessDown TimerElapsed) a)
- selectTimerElapsed :: TimerReference -> MessageSelector TimerElapsed
- sendAfter :: forall r q message. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Typeable message, NFData message) => ProcessId -> Timeout -> (TimerReference -> message) -> Eff r TimerReference
- startTimer :: forall r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Timeout -> Eff r TimerReference
- cancelTimer :: forall r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => TimerReference -> Eff r ()
- newtype Server api = Server {}
- data Synchronicity
- data family Api (api :: Type) (reply :: Synchronicity)
- fromServer :: forall api api. Iso (Server api) (Server api) ProcessId ProcessId
- proxyAsServer :: proxy api -> ProcessId -> Server api
- asServer :: forall api. ProcessId -> Server api
- type ServerReader o = Reader (Server o)
- type ServesApi o r q = (Typeable o, SetMember Process (Process q) r, Member (ServerReader o) r)
- cast :: forall r q o. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Typeable o, Typeable (Api o Asynchronous), NFData (Api o Asynchronous)) => Server o -> Api o Asynchronous -> Eff r ()
- call :: forall result api r q. (SetMember Process (Process q) r, Member Interrupts r, Typeable api, Typeable (Api api (Synchronous result)), NFData (Api api (Synchronous result)), Typeable result, NFData result, Show result, HasCallStack) => Server api -> Api api (Synchronous result) -> Eff r result
- callWithTimeout :: forall result api r q. (SetMember Process (Process q) r, Member Interrupts r, Typeable api, Typeable (Api api (Synchronous result)), NFData (Api api (Synchronous result)), Typeable result, NFData result, Show result, Member Logs r, Lifted IO q, Lifted IO r, HasCallStack) => Server api -> Api api (Synchronous result) -> Timeout -> Eff r result
- registerServer :: HasCallStack => Server o -> Eff (ServerReader o ': r) a -> Eff r a
- whereIsServer :: Member (ServerReader o) e => Eff e (Server o)
- callRegistered :: (Typeable reply, ServesApi o r q, HasCallStack, NFData reply, Show reply, NFData (Api o (Synchronous reply)), Member Interrupts r) => Api o (Synchronous reply) -> Eff r reply
- castRegistered :: (Typeable o, ServesApi o r q, HasCallStack, Member Interrupts r, NFData (Api o Asynchronous)) => Api o Asynchronous -> Eff r ()
- data InterruptCallback eff where
- InterruptCallback :: (InterruptReason -> Eff eff CallbackResult) -> InterruptCallback eff
- class ToServerPids (t :: k) where
- type ServerPids t
- toServerPids :: proxy t -> ProcessId -> ServerPids t
- data MessageCallback api eff where
- MessageCallback :: MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback api eff
- data CallbackResult where
- spawnApiServer :: forall api eff. (ToServerPids api, HasCallStack) => MessageCallback api (InterruptableProcess eff) -> InterruptCallback (ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api)
- spawnLinkApiServer :: forall api eff. (ToServerPids api, HasCallStack) => MessageCallback api (InterruptableProcess eff) -> InterruptCallback (ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api)
- spawnApiServerStateful :: forall api eff state. (HasCallStack, ToServerPids api, NFData state) => Eff (InterruptableProcess eff) state -> MessageCallback api (State state ': InterruptableProcess eff) -> InterruptCallback (State state ': ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api)
- spawnApiServerEffectful :: forall api eff serverEff. (HasCallStack, ToServerPids api, 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) (ServerPids api)
- spawnLinkApiServerEffectful :: forall api eff serverEff. (HasCallStack, ToServerPids api, 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) (ServerPids api)
- handleMessages :: forall eff a. (HasCallStack, NFData a, Typeable a) => (a -> Eff eff CallbackResult) -> MessageCallback '[] eff
- handleSelectedMessages :: forall eff a. HasCallStack => MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback '[] eff
- handleAnyMessages :: forall eff. HasCallStack => (StrictDynamic -> Eff eff CallbackResult) -> MessageCallback '[] eff
- handleCasts :: forall api eff. (HasCallStack, Typeable api, Typeable (Api api Asynchronous), NFData (Request api)) => (Api api Asynchronous -> Eff eff CallbackResult) -> MessageCallback api eff
- handleCalls :: forall api eff effScheduler. (HasCallStack, Typeable api, SetMember Process (Process effScheduler) eff, Member Interrupts eff) => (forall secret reply. (NFData reply, Typeable reply, Typeable (Api api (Synchronous reply))) => Api api (Synchronous reply) -> (Eff eff (Maybe reply, CallbackResult) -> secret) -> secret) -> MessageCallback api eff
- handleCastsAndCalls :: forall api eff effScheduler. (HasCallStack, Typeable api, Typeable (Api api Asynchronous), NFData (Request api), SetMember Process (Process effScheduler) eff, Member Interrupts eff) => (Api api Asynchronous -> Eff eff CallbackResult) -> (forall secret reply. (Typeable reply, Typeable (Api api (Synchronous reply)), NFData reply) => Api api (Synchronous reply) -> (Eff eff (Maybe reply, CallbackResult) -> secret) -> secret) -> MessageCallback api eff
- handleCallsDeferred :: forall api eff effScheduler. (HasCallStack, Typeable api, SetMember Process (Process effScheduler) eff, Member Interrupts eff) => (forall reply. (Typeable reply, NFData reply, Typeable (Api api (Synchronous reply))) => RequestOrigin (Api api (Synchronous reply)) -> Api api (Synchronous reply) -> Eff eff CallbackResult) -> MessageCallback api eff
- handleProcessDowns :: forall eff. HasCallStack => (MonitorReference -> Eff eff CallbackResult) -> MessageCallback '[] eff
- (^:) :: forall (api1 :: Type) (apis2 :: [Type]) eff. HasCallStack => MessageCallback api1 eff -> MessageCallback apis2 eff -> MessageCallback (api1 ': apis2) eff
- fallbackHandler :: forall api eff. HasCallStack => MessageCallback api eff -> MessageCallback '[] eff
- dropUnhandledMessages :: forall eff. HasCallStack => MessageCallback '[] eff
- exitOnUnhandled :: forall eff. HasCallStack => MessageCallback '[] eff
- logUnhandledMessages :: forall eff. (Member Logs eff, HasCallStack) => MessageCallback '[] eff
- stopServerOnInterrupt :: forall eff. HasCallStack => InterruptCallback eff
- data RequestOrigin request = RequestOrigin {}
- data Reply request where
- data Request api where
- Call :: forall api reply. (Typeable api, Typeable reply, NFData reply, Typeable (Api api (Synchronous reply)), NFData (Api api (Synchronous reply))) => Int -> ProcessId -> Api api (Synchronous reply) -> Request api
- Cast :: forall api. (Typeable api, Typeable (Api api Asynchronous), NFData (Api api Asynchronous)) => Api api Asynchronous -> Request api
- mkRequestOrigin :: request -> ProcessId -> Int -> RequestOrigin request
- sendReply :: forall request reply api eff q. (SetMember Process (Process q) eff, Member Interrupts eff, Typeable api, ApiType request ~ api, ReplyType request ~ reply, request ~ Api api (Synchronous reply), Typeable reply, NFData reply) => RequestOrigin request -> reply -> Eff eff ()
- data family Api (api :: Type) (reply :: Synchronicity)
- type ObserverState o = State (Observers o)
- data ObserverRegistry o
- data Observer o where
- registerObserver :: (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o, NFData o) => Observer o -> Server (ObserverRegistry o) -> Eff r ()
- forgetObserver :: (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o, NFData o) => Observer o -> Server (ObserverRegistry o) -> Eff r ()
- handleObservations :: (HasCallStack, Typeable o, SetMember Process (Process q) r, NFData (Observer o)) => (o -> Eff r CallbackResult) -> MessageCallback (Observer o) r
- toObserver :: (NFData o, Typeable o, NFData (Api (Observer o) Asynchronous)) => Server (Observer o) -> Observer o
- toObserverFor :: (Typeable a, NFData (Api a Asynchronous), Typeable o, NFData o) => (o -> Api a Asynchronous) -> Server a -> Observer o
- handleObserverRegistration :: forall o q r. (HasCallStack, Typeable o, SetMember Process (Process q) r, Member (ObserverState o) r, Member Logs r) => MessageCallback (ObserverRegistry o) r
- manageObservers :: Eff (ObserverState o ': r) a -> Eff r a
- observed :: forall o r q. (SetMember Process (Process q) r, Member (ObserverState o) r, Member Interrupts r) => o -> Eff r ()
- type ObservationQueueReader a = Reader (ObservationQueue a)
- data ObservationQueue a
- readObservationQueue :: forall o r. (Member (ObservationQueueReader o) r, HasCallStack, MonadIO (Eff r), Typeable o, Member Logs r) => Eff r o
- tryReadObservationQueue :: forall o r. (Member (ObservationQueueReader o) r, HasCallStack, MonadIO (Eff r), Typeable o, Member Logs r) => Eff r (Maybe o)
- flushObservationQueue :: forall o r. (Member (ObservationQueueReader o) r, HasCallStack, MonadIO (Eff r), Typeable o, Member Logs r) => Eff r [o]
- withObservationQueue :: forall o b e len. (HasCallStack, Typeable o, Show o, Member Logs e, Lifted IO e, Integral len, Member Interrupts e) => len -> Eff (ObservationQueueReader o ': e) b -> Eff e b
- spawnLinkObservationQueueWriter :: forall o q. (Typeable o, Show o, NFData o, NFData (Api (Observer o) Asynchronous), Member Logs q, Lifted IO q, HasCallStack) => ObservationQueue o -> Eff (InterruptableProcess q) (Observer o)
- type SchedulerIO = Reader SchedulerState ': LoggingAndIo
- type HasSchedulerIO r = (HasCallStack, Lifted IO r, SchedulerIO <:: r)
- type InterruptableProcEff = InterruptableProcess SchedulerIO
- type ProcEff = ConsProcess SchedulerIO
- defaultMain :: HasCallStack => Eff InterruptableProcEff () -> IO ()
- defaultMainWithLogWriter :: HasCallStack => LogWriter IO -> Eff InterruptableProcEff () -> IO ()
- schedule :: HasCallStack => Eff InterruptableProcEff () -> Eff LoggingAndIo ()
- schedulePure :: Eff (InterruptableProcess '[Logs, LogWriterReader PureLogWriter]) a -> Either (ExitReason NoRecovery) a
- defaultMainSingleThreaded :: HasCallStack => Eff (InterruptableProcess LoggingAndIo) () -> IO ()
- module Control.Eff.Log
- module Control.Eff.LogWriter.Async
- module Control.Eff.LogWriter.Console
- module Control.Eff.LogWriter.File
- module Control.Eff.LogWriter.UDP
- module Control.Eff.LogWriter.Capture
- module Control.Eff.LogWriter.DebugTrace
- module Control.Eff.LogWriter.IO
- module Control.Eff.LogWriter.UnixSocket
- module Control.Eff.Loop
Concurrent Processes with Message Passing Concurrency
Each process is identified by a single process id, that stays constant throughout the life cycle of a process. Also, message sending relies on these values to address messages to processes.
Instances
Bounded ProcessId Source # | |
Enum ProcessId Source # | |
Defined in Control.Eff.Concurrent.Process succ :: ProcessId -> ProcessId # pred :: ProcessId -> ProcessId # fromEnum :: ProcessId -> Int # enumFrom :: ProcessId -> [ProcessId] # enumFromThen :: ProcessId -> ProcessId -> [ProcessId] # enumFromTo :: ProcessId -> ProcessId -> [ProcessId] # enumFromThenTo :: ProcessId -> ProcessId -> ProcessId -> [ProcessId] # | |
Eq ProcessId Source # | |
Integral ProcessId Source # | |
Defined in Control.Eff.Concurrent.Process | |
Num ProcessId Source # | |
Defined in Control.Eff.Concurrent.Process | |
Ord ProcessId Source # | |
Defined in Control.Eff.Concurrent.Process | |
Read ProcessId Source # | |
Real ProcessId Source # | |
Defined in Control.Eff.Concurrent.Process toRational :: ProcessId -> Rational # | |
Show ProcessId Source # | |
NFData ProcessId Source # | |
Defined in Control.Eff.Concurrent.Process |
data ProcessDown Source #
A monitored process exited. This message is sent to a process by the scheduler, when a process that was monitored died.
Since: 0.12.0
Instances
data MonitorReference Source #
A value that contains a unique reference of a process monitoring.
Since: 0.12.0
Instances
data SomeExitReason where Source #
An existential wrapper around ExitReason
SomeExitReason :: ExitReason x -> SomeExitReason |
Instances
Eq SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process (==) :: SomeExitReason -> SomeExitReason -> Bool # (/=) :: SomeExitReason -> SomeExitReason -> Bool # | |
Ord SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process compare :: SomeExitReason -> SomeExitReason -> Ordering # (<) :: SomeExitReason -> SomeExitReason -> Bool # (<=) :: SomeExitReason -> SomeExitReason -> Bool # (>) :: SomeExitReason -> SomeExitReason -> Bool # (>=) :: SomeExitReason -> SomeExitReason -> Bool # max :: SomeExitReason -> SomeExitReason -> SomeExitReason # min :: SomeExitReason -> SomeExitReason -> SomeExitReason # | |
Show SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process showsPrec :: Int -> SomeExitReason -> ShowS # show :: SomeExitReason -> String # showList :: [SomeExitReason] -> ShowS # | |
NFData SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process rnf :: SomeExitReason -> () # |
type InterruptableProcess e = Interrupts ': ConsProcess e Source #
This adds a layer of the Interrupts
effect on top of ConsProcess
type Interrupts = Exc InterruptReason Source #
Exc
eptions containing InterruptReason
s.
See handleInterrupts
, exitOnInterrupt
or provideInterrupts
type InterruptReason = ExitReason Recoverable Source #
ExitReason
s which are recoverable are interrupts.
data ExitReason (t :: ExitRecovery) where Source #
A sum-type with reasons for why a process exists the scheduling loop, this includes errors, that can occur when scheduling messages.
ProcessFinished :: ExitReason Recoverable | A process has finished a unit of work and might exit or work on
something else. This is primarily used for interrupting infinite
server loops, allowing for additional cleanup work before
exiting (e.g. with Since: 0.13.2 |
ProcessNotRunning :: ProcessId -> ExitReason Recoverable | A process that should be running was not running. |
ProcessTimeout :: String -> ExitReason Recoverable | A |
LinkedProcessCrashed :: ProcessId -> ExitReason Recoverable | A linked process is down |
ProcessError :: String -> ExitReason Recoverable | An exit reason that has an error message and is |
ExitNormally :: ExitReason NoRecovery | A process function returned or exited without any error. |
NotRecovered :: ExitReason Recoverable -> ExitReason NoRecovery | An unhandled |
UnexpectedException :: String -> String -> ExitReason NoRecovery | An unexpected runtime exception was thrown, i.e. an exception
derived from |
Killed :: ExitReason NoRecovery | A process was cancelled (e.g. killed, in |
Instances
data ExitSeverity Source #
This value indicates whether a process exited in way consistent with the planned behaviour or not.
Instances
data ExitRecovery Source #
This kind is used to indicate if a ExitReason
can be treated like
a short interrupt which can be handled or ignored.
Instances
data ProcessState Source #
The state that a Process
is currently in.
ProcessBooting | The process has just been started but not scheduled yet. |
ProcessIdle | The process yielded it's time slice |
ProcessBusy | The process is busy with non-blocking |
ProcessBusySending | The process is busy with sending a message |
ProcessBusySendingShutdown | The process is busy with killing |
ProcessBusySendingInterrupt | The process is busy with killing |
ProcessBusyReceiving | The process blocked by a |
ProcessBusyLinking | The process blocked by a |
ProcessBusyUnlinking | The process blocked by a |
ProcessBusyMonitoring | The process blocked by a |
ProcessBusyDemonitoring | The process blocked by a |
ProcessInterrupted | The process was interrupted |
ProcessShuttingDown | The process was shutdown or crashed |
Instances
type ConsProcess r = Process r ': r Source #
Cons Process
onto a list of effects.
data MessageSelector a Source #
A function that decided if the next message will be received by
ReceiveSelectedMessage
. It conveniently is an instance of
Alternative
so the message selector can be combined:
>
> selectInt :: MessageSelector Int
> selectInt = selectMessage
>
> selectString :: MessageSelector String
> selectString = selectMessage
>
> selectIntOrString :: MessageSelector (Either Int String)
> selectIntOrString =
> Left $ selectTimeout| Right $ selectString
Instances
data ResumeProcess v where Source #
Every Process
action returns it's actual result wrapped in this type. It
will allow to signal errors as well as pass on normal results such as
incoming messages.
Interrupted :: InterruptReason -> ResumeProcess v | The current operation of the process was interrupted with a
|
ResumeWith :: a -> ResumeProcess a | The process may resume to do work, using the given result. |
Instances
data StrictDynamic Source #
Data flows between Process
es via these messages.
This is just a newtype wrapper around Dynamic
.
The reason this type exists is to force construction through the code in this
module, which always evaluates a message to normal form before
sending it to another process.
Since: 0.22.0
Instances
Show StrictDynamic Source # | |
Defined in Control.Eff.Concurrent.Process showsPrec :: Int -> StrictDynamic -> ShowS # show :: StrictDynamic -> String # showList :: [StrictDynamic] -> ShowS # |
data Process (r :: [Type -> Type]) b where Source #
The process effect is the basis for message passing concurrency. This effect describes an interface for concurrent, communicating isolated processes identified uniquely by a process-id.
Processes can raise exceptions that can be caught, exit gracefully or with an error, or be killed by other processes, with the option of ignoring the shutdown request.
Process Scheduling is implemented in different modules. All scheduler implementations should follow some basic rules:
- fair scheduling
- sending a message does not block
- receiving a message does block
- spawning a child blocks only a very moment
- a newly spawned process shall be scheduled before the parent process after
- the spawnRaw
- when the first process exists, all process should be killed immediately
FlushMessages :: Process r (ResumeProcess [StrictDynamic]) | Remove all messages from the process' message queue |
YieldProcess :: Process r (ResumeProcess ()) | In cooperative schedulers, this will give processing time to the scheduler. Every other operation implicitly serves the same purpose. Since: 0.12.0 |
SelfPid :: Process r (ResumeProcess ProcessId) | Return the current |
Spawn :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId) | Start a new process, the new process will execute an effect, the function
will return immediately with a |
SpawnLink :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId) | Start a new process, and Since: 0.12.0 |
GetProcessState :: ProcessId -> Process r (ResumeProcess (Maybe ProcessState)) | Get the process state (or |
Shutdown :: ExitReason NoRecovery -> Process r a | Shutdown the process; irregardless of the exit reason, this function never returns, |
SendShutdown :: ProcessId -> ExitReason NoRecovery -> Process r (ResumeProcess ()) | Raise an error, that can be handled. |
SendInterrupt :: ProcessId -> InterruptReason -> Process r (ResumeProcess ()) | Request that another a process interrupts. The targeted process is interrupted
and gets an |
SendMessage :: ProcessId -> StrictDynamic -> Process r (ResumeProcess ()) | Send a message to a process addressed by the |
ReceiveSelectedMessage :: forall r a. MessageSelector a -> Process r (ResumeProcess a) | Receive a message that matches a criteria.
This should block until an a message was received. The message is returned
as a |
MakeReference :: Process r (ResumeProcess Int) | Generate a unique |
Monitor :: ProcessId -> Process r (ResumeProcess MonitorReference) | Monitor another process. When the monitored process exits a
Since: 0.12.0 |
Demonitor :: MonitorReference -> Process r (ResumeProcess ()) | Remove a monitor. Since: 0.12.0 |
Link :: ProcessId -> Process r (ResumeProcess ()) | Connect the calling process to another process, such that
if one of the processes crashes (i.e. Since: 0.12.0 |
Unlink :: ProcessId -> Process r (ResumeProcess ()) | Unlink the calling process from the other process. Since: 0.12.0 |
toStrictDynamic :: (Typeable a, NFData a) => a -> StrictDynamic Source #
Deeply evaluate the given value and wrap it into a StrictDynamic
.
Since: 0.22.0
fromStrictDynamic :: Typeable a => StrictDynamic -> Maybe a Source #
Convert a StrictDynamic
back to a value.
Since: 0.22.0
unwrapStrictDynamic :: StrictDynamic -> Dynamic Source #
Convert a StrictDynamic
back to an unwrapped Dynamic
.
Since: 0.22.0
selectMessage :: Typeable t => MessageSelector t Source #
Create a message selector for a value that can be obtained by fromStrictDynamic
.
Since: 0.9.1
filterMessage :: Typeable a => (a -> Bool) -> MessageSelector a Source #
Create a message selector from a predicate.
Since: 0.9.1
selectMessageWith :: Typeable a => (a -> Maybe b) -> MessageSelector b Source #
Select a message of type a
and apply the given function to it.
If the function returns Just
The ReceiveSelectedMessage
function will
return the result (sans Maybe
).
Since: 0.9.1
selectDynamicMessage :: (StrictDynamic -> Maybe a) -> MessageSelector a Source #
Create a message selector.
Since: 0.9.1
selectAnyMessage :: MessageSelector StrictDynamic Source #
Create a message selector that will match every message. This is lazy
because the result is not force
ed.
Since: 0.9.1
toExitRecovery :: ExitReason r -> ExitRecovery Source #
Get the ExitRecovery
toExitSeverity :: ExitReason e -> ExitSeverity Source #
Get the ExitSeverity
of a ExitReason
.
isBecauseDown :: Maybe ProcessId -> ExitReason r -> Bool Source #
A predicate for linked process crashes.
provideInterruptsShutdown :: forall e a. Eff (InterruptableProcess e) a -> Eff (ConsProcess e) a Source #
Handle all InterruptReason
s of an InterruptableProcess
by
wrapping them up in NotRecovered
and then do a process Shutdown
.
handleInterrupts :: (HasCallStack, Member Interrupts r) => (InterruptReason -> Eff r a) -> Eff r a -> Eff r a Source #
Handle InterruptReason
s arising during process operations, e.g.
when a linked process crashes while we wait in a receiveSelectedMessage
via a call to interrupt
.
tryUninterrupted :: (HasCallStack, Member Interrupts r) => Eff r a -> Eff r (Either InterruptReason a) Source #
Like handleInterrupts
, but instead of passing the InterruptReason
to a handler function, Either
is returned.
Since: 0.13.2
logInterrupts :: forall r. (Member Logs r, HasCallStack, Member Interrupts r) => Eff r () -> Eff r () Source #
Handle interrupts by logging them with logProcessExit
and otherwise
ignoring them.
exitOnInterrupt :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r) => Eff r a -> Eff r a Source #
Handle InterruptReason
s arising during process operations, e.g.
when a linked process crashes while we wait in a receiveSelectedMessage
via a call to interrupt
.
provideInterrupts :: HasCallStack => Eff (Interrupts ': r) a -> Eff r (Either InterruptReason a) Source #
Handle InterruptReason
s arising during process operations, e.g.
when a linked process crashes while we wait in a receiveSelectedMessage
via a call to interrupt
.
mergeEitherInterruptAndExitReason :: Either InterruptReason (ExitReason NoRecovery) -> ExitReason NoRecovery Source #
Wrap all (left) InterruptReason
s into NotRecovered
and
return the (right) NoRecovery
ExitReason
s as is.
interrupt :: (HasCallStack, Member Interrupts r) => InterruptReason -> Eff r a Source #
Throw an InterruptReason
, can be handled by handleInterrupts
or
exitOnInterrupt
or provideInterrupts
.
isCrash :: ExitReason x -> Bool Source #
A predicate for crashes. A crash happens when a process exits
with an ExitReason
other than ExitNormally
isRecoverable :: ExitReason x -> Bool Source #
A predicate for recoverable exit reasons. This predicate defines the
exit reasons which functions such as executeAndResume
fromSomeExitReason :: SomeExitReason -> Either (ExitReason NoRecovery) InterruptReason Source #
Partition a SomeExitReason
back into either a NoRecovery
or a Recoverable
ExitReason
toCrashReason :: ExitReason x -> Maybe Text Source #
Print a ExitReason
to Just
a formatted String
when isCrash
is True
.
This can be useful in combination with view patterns, e.g.:
logCrash :: ExitReason -> Eff e () logCrash (toCrashReason -> Just reason) = logError reason logCrash _ = return ()
Though this can be improved to:
logCrash = traverse_ logError . toCrashReason
logProcessExit :: forall e x. (Member Logs e, HasCallStack) => ExitReason x -> Eff e () Source #
Log the ExitReason
s
executeAndResume :: forall q r v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r (Either (ExitReason Recoverable) v) Source #
Execute a and action and return the result;
if the process is interrupted by an error or exception, or an explicit
shutdown from another process, or through a crash of a linked process, i.e.
whenever the exit reason satisfies isRecoverable
, return the exit reason.
executeAndResumeOrExit :: forall r q v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r v Source #
Execute a Process
action and resume the process, exit
the process when an Interrupts
was raised. Use executeAndResume
to catch
interrupts.
executeAndResumeOrThrow :: forall q r v. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => Process q (ResumeProcess v) -> Eff r v Source #
Execute a Process
action and resume the process, exit
the process when an Interrupts
was raised. Use executeAndResume
to catch
interrupts.
yieldProcess :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => Eff r () Source #
Use executeAndResumeOrExit
to execute YieldProcess
. Refer to YieldProcess
for more information.
sendMessage :: forall r q o. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o, NFData o) => ProcessId -> o -> Eff r () Source #
Send a message to a process addressed by the ProcessId
.
See SendMessage
.
The message will be reduced to normal form (rnf
) by/in the caller process.
sendAnyMessage :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => ProcessId -> StrictDynamic -> Eff r () Source #
Send a Dynamic
value to a process addressed by the ProcessId
.
See SendMessage
.
sendShutdown :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => ProcessId -> ExitReason NoRecovery -> Eff r () Source #
Exit a process addressed by the ProcessId
. The process will exit,
it might do some cleanup, but is ultimately unrecoverable.
See SendShutdown
.
sendInterrupt :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => ProcessId -> InterruptReason -> Eff r () Source #
Interrupts a process addressed by the ProcessId
. The process might exit,
or it may continue.
| Like sendInterrupt
, but also return True
iff the process to exit exists.
spawn :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId Source #
Start a new process, the new process will execute an effect, the function
will return immediately with a ProcessId
. If the new process is
interrupted, the process will Shutdown
with the InterruptReason
wrapped in NotRecovered
. For specific use cases it might be better to use
spawnRaw
.
spawn_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r () Source #
Like spawn
but return ()
.
spawnLink :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId Source #
Start a new process, and immediately link to it.
Since: 0.12.0
spawnRaw :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r ProcessId Source #
Start a new process, the new process will execute an effect, the function
will return immediately with a ProcessId
. The spawned process has only the
raw ConsProcess
effects. For non-library code spawn
might be better
suited.
spawnRaw_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r () Source #
Like spawnRaw
but return ()
.
isProcessAlive :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r Bool Source #
Return True
if the process is alive.
Since: 0.12.0
receiveAnyMessage :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff r StrictDynamic Source #
Block until a message was received.
See ReceiveSelectedMessage
for more documentation.
receiveSelectedMessage :: forall r q a. (HasCallStack, Show a, SetMember Process (Process q) r, Member Interrupts r) => MessageSelector a -> Eff r a Source #
Block until a message was received, that is not Nothing
after applying
a callback to it.
See ReceiveSelectedMessage
for more documentation.
receiveMessage :: forall a r q. (HasCallStack, Typeable a, NFData a, Show a, SetMember Process (Process q) r, Member Interrupts r) => Eff r a Source #
Receive and cast the message to some Typeable
instance.
See ReceiveSelectedMessage
for more documentation.
This will wait for a message of the return type using receiveSelectedMessage
flushMessages :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff r [StrictDynamic] Source #
Remove and return all messages currently enqueued in the process message queue.
Since: 0.12.0
receiveSelectedLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => MessageSelector a -> (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult Source #
Enter a loop to receive messages and pass them to a callback, until the
function returns Just
a result.
Only the messages of the given type will be received.
If the process is interrupted by an exception of by a SendShutdown
from
another process, with an exit reason that satisfies isRecoverable
, then
the callback will be invoked with
, otherwise the
process will be exited with the same reason using Left
ExitReason
exitBecause
.
See also ReceiveSelectedMessage
for more documentation.
receiveAnyLoop :: forall r q endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => (Either InterruptReason StrictDynamic -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult Source #
Like receiveSelectedLoop
but not selective.
See also selectAnyMessage
, receiveSelectedLoop
.
receiveLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack, NFData a, Typeable a) => (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult Source #
Like receiveSelectedLoop
but refined to casting to a specific Typeable
using selectMessage
.
self :: (HasCallStack, SetMember Process (Process q) r) => Eff r ProcessId Source #
Returns the ProcessId
of the current process.
makeReference :: (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff r Int Source #
Generate a unique Int
for the current process.
monitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r MonitorReference Source #
Monitor another process. When the monitored process exits a
ProcessDown
is sent to the calling process.
The return value is a unique identifier for that monitor.
There can be multiple monitors on the same process,
and a message for each will be sent.
If the process is already dead, the ProcessDown
message
will be sent immediately, without exit reason
Since: 0.12.0
demonitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => MonitorReference -> Eff r () Source #
Remove a monitor created with monitor
.
Since: 0.12.0
withMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> (MonitorReference -> Eff r a) -> Eff r a Source #
receiveWithMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r, Typeable a, Show a) => ProcessId -> MessageSelector a -> Eff r (Either ProcessDown a) Source #
A MessageSelector
for receiving either a monitor of the
given process or another message.
Since: 0.12.0
becauseProcessIsDown :: ProcessDown -> InterruptReason Source #
Make an InterruptReason
for a ProcessDown
message.
For example: doSomething >>= either (interrupt . becauseProcessIsDown) return
Since: 0.12.0
selectProcessDown :: MonitorReference -> MessageSelector ProcessDown Source #
A MessageSelector
for the ProcessDown
message of a specific
process.
Since: 0.12.0
linkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r () Source #
Connect the calling process to another process, such that
if one of the processes crashes (i.e. isCrash
returns True
), the other
is shutdown with the ExitReason
LinkedProcessCrashed
.
Since: 0.12.0
unlinkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => ProcessId -> Eff r () Source #
Unlink the calling process from the other process.
Since: 0.12.0
exitBecause :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => ExitReason NoRecovery -> Eff r a Source #
Exit the process with a ExitReason
.
exitNormally :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => Eff r a Source #
Exit the process.
exitWithError :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => String -> Eff r a Source #
Exit the process with an error.
Timers and Timeouts
data TimerElapsed Source #
A value to be sent when timer started with startTimer
has elapsed.
Since: 0.12.0
Instances
Eq TimerElapsed Source # | |
Defined in Control.Eff.Concurrent.Process.Timer (==) :: TimerElapsed -> TimerElapsed -> Bool # (/=) :: TimerElapsed -> TimerElapsed -> Bool # | |
Ord TimerElapsed Source # | |
Defined in Control.Eff.Concurrent.Process.Timer compare :: TimerElapsed -> TimerElapsed -> Ordering # (<) :: TimerElapsed -> TimerElapsed -> Bool # (<=) :: TimerElapsed -> TimerElapsed -> Bool # (>) :: TimerElapsed -> TimerElapsed -> Bool # (>=) :: TimerElapsed -> TimerElapsed -> Bool # max :: TimerElapsed -> TimerElapsed -> TimerElapsed # min :: TimerElapsed -> TimerElapsed -> TimerElapsed # | |
Show TimerElapsed Source # | |
Defined in Control.Eff.Concurrent.Process.Timer showsPrec :: Int -> TimerElapsed -> ShowS # show :: TimerElapsed -> String # showList :: [TimerElapsed] -> ShowS # | |
NFData TimerElapsed Source # | |
Defined in Control.Eff.Concurrent.Process.Timer rnf :: TimerElapsed -> () # |
data TimerReference Source #
The reference to a timer started by startTimer
, required to stop
a timer via cancelTimer
.
Since: 0.12.0
Instances
A number of micro seconds.
Since: 0.12.0
Instances
Enum Timeout Source # | |
Eq Timeout Source # | |
Integral Timeout Source # | |
Defined in Control.Eff.Concurrent.Process.Timer | |
Num Timeout Source # | |
Ord Timeout Source # | |
Defined in Control.Eff.Concurrent.Process.Timer | |
Real Timeout Source # | |
Defined in Control.Eff.Concurrent.Process.Timer toRational :: Timeout -> Rational # | |
Show Timeout Source # | |
NFData Timeout Source # | |
Defined in Control.Eff.Concurrent.Process.Timer |
receiveAfter :: forall a r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Typeable a, NFData a, Show a) => Timeout -> Eff r (Maybe a) Source #
Wait for a message of the given type for the given time. When no message
arrives in time, return Nothing
. This is based on
receiveSelectedAfter
.
Since: 0.12.0
receiveSelectedAfter :: forall a r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Show a) => MessageSelector a -> Timeout -> Eff r (Either TimerElapsed a) Source #
Wait for a message of the given type for the given time. When no message
arrives in time, return Left
TimerElapsed
. This is based on
selectTimerElapsed
and startTimer
.
Since: 0.12.0
receiveSelectedWithMonitorAfter :: forall a r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Show a) => ProcessId -> MessageSelector a -> Timeout -> Eff r (Either (Either ProcessDown TimerElapsed) a) Source #
Like receiveWithMonitor
combined with receiveSelectedAfter
.
Since: 0.22.0
selectTimerElapsed :: TimerReference -> MessageSelector TimerElapsed Source #
A MessageSelector
matching TimerElapsed
messages created by
startTimer
.
Since: 0.12.0
sendAfter :: forall r q message. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Typeable message, NFData message) => ProcessId -> Timeout -> (TimerReference -> message) -> Eff r TimerReference Source #
Send a message to a given process after waiting. The message is created by
applying the function parameter to the TimerReference
, such that the
message can directly refer to the timer.
Since: 0.12.0
startTimer :: forall r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Timeout -> Eff r TimerReference Source #
Start a new timer, after the time has elapsed, TimerElapsed
is sent to
calling process. The message also contains the TimerReference
returned by
this function. Use cancelTimer
to cancel the timer. Use
selectTimerElapsed
to receive the message using receiveSelectedMessage
.
To receive messages with guarded with a timeout see receiveAfter
.
Since: 0.12.0
cancelTimer :: forall r q. (Lifted IO q, HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => TimerReference -> Eff r () Source #
Cancel a timer started with startTimer
.
Since: 0.12.0
Data Types and Functions for APIs (aka Protocols)
Instances
Eq (Server api) Source # | |
Ord (Server api) Source # | |
Defined in Control.Eff.Concurrent.Api | |
Typeable api => Show (Server api) Source # | |
NFData (Server api) Source # | |
Defined in Control.Eff.Concurrent.Api |
data Synchronicity Source #
The (promoted) constructors of this type specify (at the type level) the
reply behavior of a specific constructor of an Api
instance.
Synchronous Type | Specify that handling a request is a blocking operation
with a specific return type, e.g. |
Asynchronous | Non-blocking, asynchronous, request handling |
data family Api (api :: Type) (reply :: Synchronicity) Source #
This data family defines an API, a communication interface description between at least two processes. The processes act as servers or client(s) regarding a specific instance of this type.
The first parameter is usually a user defined phantom type that identifies
the Api
instance.
The second parameter specifies if a specific constructor of an (GADT-like)
Api
instance is Synchronous
, i.e. returns a result and blocks the caller
or if it is Asynchronous
Example:
data BookShop deriving Typeable data instance Api BookShop r where RentBook :: BookId -> Api BookShop ('Synchronous (Either RentalError RentalId)) BringBack :: RentalId -> Api BookShop 'Asynchronous type BookId = Int type RentalId = Int type RentalError = String
Instances
NFData (Api (ObserverRegistry o) r) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer rnf :: Api (ObserverRegistry o) r -> () # | |
NFData o => NFData (Api (Observer o) Asynchronous) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer rnf :: Api (Observer o) Asynchronous -> () # | |
data Api (Observer o) r Source # | A minimal Api for handling observations.
This is one simple way of receiving observations - of course users can use
any other Since: 0.16.0 |
Defined in Control.Eff.Concurrent.Api.Observer data Api (Observer o) r where
| |
data Api (SomeMessage a) s Source # | |
Defined in Control.Eff.Concurrent.Api.GenServer data Api (SomeMessage a) s where
| |
data Api (ObserverRegistry o) r Source # | Api for managing observers. This can be added to any server for any number of different observation types.
The functions Since: 0.16.0 |
Defined in Control.Eff.Concurrent.Api.Observer data Api (ObserverRegistry o) r where
|
proxyAsServer :: proxy api -> ProcessId -> Server api Source #
Client Functions for Consuming APIs
type ServerReader o = Reader (Server o) Source #
The reader effect for ProcessId
s for Api
s, see registerServer
type ServesApi o r q = (Typeable o, SetMember Process (Process q) r, Member (ServerReader o) r) Source #
cast :: forall r q o. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r, Typeable o, Typeable (Api o Asynchronous), NFData (Api o Asynchronous)) => Server o -> Api o Asynchronous -> Eff r () Source #
Send an Api
request that has no return value and return as fast as
possible. The type signature enforces that the corresponding Api
clause is
Asynchronous
. The operation never fails, if it is important to know if the
message was delivered, use call
instead.
The message will be reduced to normal form (rnf
) in the caller process.
call :: forall result api r q. (SetMember Process (Process q) r, Member Interrupts r, Typeable api, Typeable (Api api (Synchronous result)), NFData (Api api (Synchronous result)), Typeable result, NFData result, Show result, HasCallStack) => Server api -> Api api (Synchronous result) -> Eff r result Source #
Send an Api
request and wait for the server to return a result value.
The type signature enforces that the corresponding Api
clause is
Synchronous
.
Always prefer callWithTimeout
over call
callWithTimeout :: forall result api r q. (SetMember Process (Process q) r, Member Interrupts r, Typeable api, Typeable (Api api (Synchronous result)), NFData (Api api (Synchronous result)), Typeable result, NFData result, Show result, Member Logs r, Lifted IO q, Lifted IO r, HasCallStack) => Server api -> Api api (Synchronous result) -> Timeout -> Eff r result Source #
Send an Api
request and wait for the server to return a result value.
The type signature enforces that the corresponding Api
clause is
Synchronous
.
If the server that was called dies, this function interrupts the
process with ProcessDown
.
If the server takes longer to reply than the given timeout, this
function interrupts the process with ProcessTimeout
.
Always prefer this function over call
Since: 0.22.0
registerServer :: HasCallStack => Server o -> Eff (ServerReader o ': r) a -> Eff r a Source #
Run a reader effect that contains the one server handling a specific
Api
instance.
whereIsServer :: Member (ServerReader o) e => Eff e (Server o) Source #
Get the Server
registered with registerServer
.
callRegistered :: (Typeable reply, ServesApi o r q, HasCallStack, NFData reply, Show reply, NFData (Api o (Synchronous reply)), Member Interrupts r) => Api o (Synchronous reply) -> Eff r reply Source #
Like call
but take the Server
from the reader provided by
registerServer
.
castRegistered :: (Typeable o, ServesApi o r q, HasCallStack, Member Interrupts r, NFData (Api o Asynchronous)) => Api o Asynchronous -> Eff r () Source #
Like cast
but take the Server
from the reader provided by
registerServer
.
Server Functions for Providing APIs
data InterruptCallback eff where Source #
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
InterruptCallback :: (InterruptReason -> Eff eff CallbackResult) -> InterruptCallback eff |
Instances
Default (InterruptCallback eff) Source # | |
Defined in Control.Eff.Concurrent.Api.Server def :: InterruptCallback eff # |
class ToServerPids (t :: k) where Source #
Helper type class for the return values of spawnApiServer
et al.
Since: 0.13.2
type ServerPids t Source #
toServerPids :: proxy t -> ProcessId -> ServerPids t Source #
Instances
ToServerPids api1 => ToServerPids (api1 :: Type) Source # | |
Defined in Control.Eff.Concurrent.Api.Server type ServerPids api1 :: Type Source # toServerPids :: proxy api1 -> ProcessId -> ServerPids api1 Source # | |
ToServerPids ([] :: [k]) Source # | |
Defined in Control.Eff.Concurrent.Api.Server type ServerPids [] :: Type Source # toServerPids :: proxy [] -> ProcessId -> ServerPids [] Source # | |
(ToServerPids api1, ToServerPids api2) => ToServerPids (api1 ': api2 :: [Type]) Source # | |
Defined in Control.Eff.Concurrent.Api.Server type ServerPids (api1 ': api2) :: Type Source # toServerPids :: proxy (api1 ': api2) -> ProcessId -> ServerPids (api1 ': api2) Source # |
data MessageCallback api eff where Source #
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 of the handler function is a CallbackResult
.
Since: 0.13.2
MessageCallback :: MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback api eff |
Instances
Semigroup (MessageCallback api eff) Source # | |
Defined in Control.Eff.Concurrent.Api.Server (<>) :: MessageCallback api eff -> MessageCallback api eff -> MessageCallback api eff # sconcat :: NonEmpty (MessageCallback api eff) -> MessageCallback api eff # stimes :: Integral b => b -> MessageCallback api eff -> MessageCallback api eff # | |
Monoid (MessageCallback api eff) Source # | |
Defined in Control.Eff.Concurrent.Api.Server mempty :: MessageCallback api eff # mappend :: MessageCallback api eff -> MessageCallback api eff -> MessageCallback api eff # mconcat :: [MessageCallback api eff] -> MessageCallback api eff # | |
Default (MessageCallback api eff) Source # | |
Defined in Control.Eff.Concurrent.Api.Server def :: MessageCallback api eff # |
data CallbackResult where Source #
A command to the server loop started by apiServerLoop
.
Typically returned by a MessageCallback
to indicate if the server
should continue or stop.
Since: 0.13.2
AwaitNext :: CallbackResult | Tell the server to keep the server loop running |
StopServer :: InterruptReason -> CallbackResult | Tell the server to exit, this will cause |
spawnApiServer :: forall api eff. (ToServerPids api, HasCallStack) => MessageCallback api (InterruptableProcess eff) -> InterruptCallback (ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api) Source #
Serve an Api
in a newly spawned process.
Since: 0.13.2
spawnLinkApiServer :: forall api eff. (ToServerPids api, HasCallStack) => MessageCallback api (InterruptableProcess eff) -> InterruptCallback (ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api) Source #
Serve an Api
in a newly spawned -and linked - process.
Since: 0.14.2
spawnApiServerStateful :: forall api eff state. (HasCallStack, ToServerPids api, NFData state) => Eff (InterruptableProcess eff) state -> MessageCallback api (State state ': InterruptableProcess eff) -> InterruptCallback (State state ': ConsProcess eff) -> Eff (InterruptableProcess eff) (ServerPids api) Source #
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
spawnApiServerEffectful :: forall api eff serverEff. (HasCallStack, ToServerPids api, 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) (ServerPids api) Source #
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
spawnLinkApiServerEffectful :: forall api eff serverEff. (HasCallStack, ToServerPids api, 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) (ServerPids api) Source #
Server an Api
in a newly spawned process; The caller provides an
effect handler for arbitrary effects used by the server callbacks.
Links to the calling process like linkProcess
would.
Since: 0.14.2
handleMessages :: forall eff a. (HasCallStack, NFData a, Typeable a) => (a -> Eff eff CallbackResult) -> MessageCallback '[] eff Source #
A smart constructor for MessageCallback
s
Since: 0.13.2
handleSelectedMessages :: forall eff a. HasCallStack => MessageSelector a -> (a -> Eff eff CallbackResult) -> MessageCallback '[] eff Source #
A smart constructor for MessageCallback
s
Since: 0.13.2
handleAnyMessages :: forall eff. HasCallStack => (StrictDynamic -> Eff eff CallbackResult) -> MessageCallback '[] eff Source #
A smart constructor for MessageCallback
s
Since: 0.13.2
handleCasts :: forall api eff. (HasCallStack, Typeable api, Typeable (Api api Asynchronous), NFData (Request api)) => (Api api Asynchronous -> Eff eff CallbackResult) -> MessageCallback api eff Source #
A smart constructor for MessageCallback
s
Since: 0.13.2
handleCalls :: forall api eff effScheduler. (HasCallStack, Typeable api, SetMember Process (Process effScheduler) eff, Member Interrupts eff) => (forall secret reply. (NFData reply, Typeable reply, Typeable (Api api (Synchronous reply))) => Api api (Synchronous reply) -> (Eff eff (Maybe reply, CallbackResult) -> secret) -> secret) -> MessageCallback api eff Source #
A smart constructor for MessageCallback
s
Example
handleCalls ( (RentBook bookId customerId) runCall -> runCall $ do rentalIdE <- rentBook bookId customerId case rentalIdE of -- on fail we just don't send a reply, let the caller run into -- timeout Left err -> return (Nothing, AwaitNext) Right rentalId -> return (Just rentalId, AwaitNext))
Since: 0.13.2
handleCastsAndCalls :: forall api eff effScheduler. (HasCallStack, Typeable api, Typeable (Api api Asynchronous), NFData (Request api), SetMember Process (Process effScheduler) eff, Member Interrupts eff) => (Api api Asynchronous -> Eff eff CallbackResult) -> (forall secret reply. (Typeable reply, Typeable (Api api (Synchronous reply)), NFData reply) => Api api (Synchronous reply) -> (Eff eff (Maybe reply, CallbackResult) -> secret) -> secret) -> MessageCallback api eff Source #
A smart constructor for MessageCallback
s
Since: 0.13.2
handleCallsDeferred :: forall api eff effScheduler. (HasCallStack, Typeable api, SetMember Process (Process effScheduler) eff, Member Interrupts eff) => (forall reply. (Typeable reply, NFData reply, Typeable (Api api (Synchronous reply))) => RequestOrigin (Api api (Synchronous reply)) -> Api api (Synchronous reply) -> Eff eff CallbackResult) -> MessageCallback api eff Source #
A variation of handleCalls
that allows to defer a reply to a call.
Since: 0.14.2
handleProcessDowns :: forall eff. HasCallStack => (MonitorReference -> Eff eff CallbackResult) -> MessageCallback '[] eff Source #
A smart constructor for MessageCallback
s
Since: 0.13.2
(^:) :: forall (api1 :: Type) (apis2 :: [Type]) eff. HasCallStack => MessageCallback api1 eff -> MessageCallback apis2 eff -> MessageCallback (api1 ': apis2) eff infixr 5 Source #
Compose two Api
s to a type-level pair of them.
handleCalls api1calls ^: handleCalls api2calls ^:
Since: 0.13.2
fallbackHandler :: forall api eff. HasCallStack => MessageCallback api eff -> MessageCallback '[] eff Source #
Make a fallback handler, i.e. a handler to which no other can be composed to from the right.
Since: 0.13.2
dropUnhandledMessages :: forall eff. HasCallStack => MessageCallback '[] eff Source #
A fallbackHandler
that drops the left-over messages.
Since: 0.13.2
exitOnUnhandled :: forall eff. HasCallStack => MessageCallback '[] eff Source #
A fallbackHandler
that terminates if there are unhandled messages.
Since: 0.13.2
logUnhandledMessages :: forall eff. (Member Logs eff, HasCallStack) => MessageCallback '[] eff Source #
A fallbackHandler
that drops the left-over messages.
Since: 0.13.2
stopServerOnInterrupt :: forall eff. HasCallStack => InterruptCallback eff Source #
A smart constructor for InterruptCallback
s
Since: 0.13.2
Encapsulate Api
s Cast
s as well as Call
s and their Reply
s
data RequestOrigin request Source #
Instances
data Reply request where Source #
The wrapper around replies to Call
s.
Since: 0.15.0
data Request api where Source #
A wrapper sum type for calls and casts for the methods of an Api
subtype
Since: 0.15.0
Call :: forall api reply. (Typeable api, Typeable reply, NFData reply, Typeable (Api api (Synchronous reply)), NFData (Api api (Synchronous reply))) => Int -> ProcessId -> Api api (Synchronous reply) -> Request api | |
Cast :: forall api. (Typeable api, Typeable (Api api Asynchronous), NFData (Api api Asynchronous)) => Api api Asynchronous -> Request api |
mkRequestOrigin :: request -> ProcessId -> Int -> RequestOrigin request Source #
TODO remove
sendReply :: forall request reply api eff q. (SetMember Process (Process q) eff, Member Interrupts eff, Typeable api, ApiType request ~ api, ReplyType request ~ reply, request ~ Api api (Synchronous reply), Typeable reply, NFData reply) => RequestOrigin request -> reply -> Eff eff () Source #
Observer Functions for Events and Event Listener
data family Api (api :: Type) (reply :: Synchronicity) Source #
This data family defines an API, a communication interface description between at least two processes. The processes act as servers or client(s) regarding a specific instance of this type.
The first parameter is usually a user defined phantom type that identifies
the Api
instance.
The second parameter specifies if a specific constructor of an (GADT-like)
Api
instance is Synchronous
, i.e. returns a result and blocks the caller
or if it is Asynchronous
Example:
data BookShop deriving Typeable data instance Api BookShop r where RentBook :: BookId -> Api BookShop ('Synchronous (Either RentalError RentalId)) BringBack :: RentalId -> Api BookShop 'Asynchronous type BookId = Int type RentalId = Int type RentalError = String
Instances
NFData (Api (ObserverRegistry o) r) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer rnf :: Api (ObserverRegistry o) r -> () # | |
NFData o => NFData (Api (Observer o) Asynchronous) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer rnf :: Api (Observer o) Asynchronous -> () # | |
data Api (Observer o) r Source # | A minimal Api for handling observations.
This is one simple way of receiving observations - of course users can use
any other Since: 0.16.0 |
Defined in Control.Eff.Concurrent.Api.Observer data Api (Observer o) r where
| |
data Api (SomeMessage a) s Source # | |
Defined in Control.Eff.Concurrent.Api.GenServer data Api (SomeMessage a) s where
| |
data Api (ObserverRegistry o) r Source # | Api for managing observers. This can be added to any server for any number of different observation types.
The functions Since: 0.16.0 |
Defined in Control.Eff.Concurrent.Api.Observer data Api (ObserverRegistry o) r where
|
type ObserverState o = State (Observers o) Source #
Alias for the effect that contains the observers managed by manageObservers
data ObserverRegistry o Source #
An Api
for managing Observer
s, encompassing registration and de-registration of
Observer
s.
Since: 0.16.0
Instances
NFData (Api (ObserverRegistry o) r) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer rnf :: Api (ObserverRegistry o) r -> () # | |
data Api (ObserverRegistry o) r Source # | Api for managing observers. This can be added to any server for any number of different observation types.
The functions Since: 0.16.0 |
Defined in Control.Eff.Concurrent.Api.Observer data Api (ObserverRegistry o) r where
|
data Observer o where Source #
Describes a process that observes another via Asynchronous
Api
messages.
An observer consists of a filter and a process id. The filter converts an observation to
a message understood by the observer process, and the ProcessId
is used to send the message.
Since: 0.16.0
Observer :: (Show (Server p), Typeable p, Typeable o, NFData o, NFData (Api p Asynchronous)) => (o -> Maybe (Api p Asynchronous)) -> Server p -> Observer o |
Instances
Eq (Observer o) Source # | |
Ord (Observer o) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer | |
Show (Observer o) Source # | |
NFData o => NFData (Observer o) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer | |
NFData o => NFData (Api (Observer o) Asynchronous) Source # | |
Defined in Control.Eff.Concurrent.Api.Observer rnf :: Api (Observer o) Asynchronous -> () # | |
data Api (Observer o) r Source # | A minimal Api for handling observations.
This is one simple way of receiving observations - of course users can use
any other Since: 0.16.0 |
Defined in Control.Eff.Concurrent.Api.Observer data Api (Observer o) r where
|
registerObserver :: (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o, NFData o) => Observer o -> Server (ObserverRegistry o) -> Eff r () Source #
And an Observer
to the set of recipients for all observations reported by observed
.
Note that the observers are keyed by the observing process, i.e. a previous entry for the process
contained in the Observer
is overwritten. If you want multiple entries for a single process, just
combine several filter functions.
Since: 0.16.0
forgetObserver :: (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o, NFData o) => Observer o -> Server (ObserverRegistry o) -> Eff r () Source #
Send the ForgetObserver
message
Since: 0.16.0
handleObservations :: (HasCallStack, Typeable o, SetMember Process (Process q) r, NFData (Observer o)) => (o -> Eff r CallbackResult) -> MessageCallback (Observer o) r Source #
Based on the Api
instance for Observer
this simplified writing
a callback handler for observations. In order to register to
and ObserverRegistry
use toObserver
.
Since: 0.16.0
toObserver :: (NFData o, Typeable o, NFData (Api (Observer o) Asynchronous)) => Server (Observer o) -> Observer o Source #
Use a Server
as an Observer
for handleObservations
.
Since: 0.16.0
toObserverFor :: (Typeable a, NFData (Api a Asynchronous), Typeable o, NFData o) => (o -> Api a Asynchronous) -> Server a -> Observer o Source #
handleObserverRegistration :: forall o q r. (HasCallStack, Typeable o, SetMember Process (Process q) r, Member (ObserverState o) r, Member Logs r) => MessageCallback (ObserverRegistry o) r Source #
Provide the implementation for the ObserverRegistry
Api, this handled RegisterObserver
and ForgetObserver
messages. It also adds the ObserverState
constraint to the effect list.
Since: 0.16.0
manageObservers :: Eff (ObserverState o ': r) a -> Eff r a Source #
Keep track of registered Observer
s.
Handle the ObserverState
introduced by handleObserverRegistration
.
Since: 0.16.0
observed :: forall o r q. (SetMember Process (Process q) r, Member (ObserverState o) r, Member Interrupts r) => o -> Eff r () Source #
Report an observation to all observers.
The process needs to manageObservers
and to handleObserverRegistration
.
Since: 0.16.0
Capture Observation in a FIFO Queue
type ObservationQueueReader a = Reader (ObservationQueue a) Source #
A Reader
for an ObservationQueue
.
data ObservationQueue a Source #
Contains a TBQueue
capturing observations.
See spawnLinkObservationQueueWriter
, readObservationQueue
.
readObservationQueue :: forall o r. (Member (ObservationQueueReader o) r, HasCallStack, MonadIO (Eff r), Typeable o, Member Logs r) => Eff r o Source #
Read queued observations captured and enqueued in the shared TBQueue
by spawnLinkObservationQueueWriter
.
This blocks until something was captured or an interrupt or exceptions was thrown. For a non-blocking
variant use tryReadObservationQueue
or flushObservationQueue
.
tryReadObservationQueue :: forall o r. (Member (ObservationQueueReader o) r, HasCallStack, MonadIO (Eff r), Typeable o, Member Logs r) => Eff r (Maybe o) Source #
Read queued observations captured and enqueued in the shared TBQueue
by spawnLinkObservationQueueWriter
.
Return the oldest enqueued observation immediately or Nothing
if the queue is empty.
Use readObservationQueue
to block until an observation is observed.
flushObservationQueue :: forall o r. (Member (ObservationQueueReader o) r, HasCallStack, MonadIO (Eff r), Typeable o, Member Logs r) => Eff r [o] Source #
Read at once all currently queued observations captured and enqueued
in the shared TBQueue
by spawnLinkObservationQueueWriter
.
This returns immediately all currently enqueued observations.
For a blocking variant use readObservationQueue
.
withObservationQueue :: forall o b e len. (HasCallStack, Typeable o, Show o, Member Logs e, Lifted IO e, Integral len, Member Interrupts e) => len -> Eff (ObservationQueueReader o ': e) b -> Eff e b Source #
Create a mutable queue for observations. Use spawnLinkObservationQueueWriter
for a simple way to get
a process that enqueues all observations.
Example
withObservationQueue 100 $ do q <- ask @(ObservationQueueReader TestEvent) wq <- spawnLinkObservationQueueWriter q registerObserver wq testServer ... cast testServer DoSomething evt <- readObservationQueue @TestEvent ...
Since: 0.18.0
spawnLinkObservationQueueWriter :: forall o q. (Typeable o, Show o, NFData o, NFData (Api (Observer o) Asynchronous), Member Logs q, Lifted IO q, HasCallStack) => ObservationQueue o -> Eff (InterruptableProcess q) (Observer o) Source #
Spawn a process that can be used as an Observer
that enqueues the observations into an
ObservationQueue
. See withObservationQueue
for an example.
The observations can be obtained by readObservationQueue
. All observations are captured up to
the queue size limit, such that the first message received will be first message
returned by readObservationQueue
.
Since: 0.18.0
Scheduler Process Effect Handler
Concurrent Scheduler
type SchedulerIO = Reader SchedulerState ': LoggingAndIo Source #
The concrete list of Eff
ects for this scheduler implementation.
type HasSchedulerIO r = (HasCallStack, Lifted IO r, SchedulerIO <:: r) Source #
Type class constraint to indicate that an effect union contains the effects required by every process and the scheduler implementation itself.
type InterruptableProcEff = InterruptableProcess SchedulerIO Source #
The concrete list of the effects, that the Process
uses
type ProcEff = ConsProcess SchedulerIO Source #
The concrete list of Eff
ects of processes compatible with this scheduler.
This builds upon SchedulerIO
.
defaultMain :: HasCallStack => Eff InterruptableProcEff () -> IO () Source #
Start the message passing concurrency system then execute a Process
on
top of SchedulerIO
effect. All logging is sent to standard output.
defaultMainWithLogWriter :: HasCallStack => LogWriter IO -> Eff InterruptableProcEff () -> IO () Source #
Start the message passing concurrency system then execute a Process
on
top of SchedulerIO
effect. All logging is sent to standard output.
schedule :: HasCallStack => Eff InterruptableProcEff () -> Eff LoggingAndIo () Source #
This is the main entry point to running a message passing concurrency
application. This function takes a Process
on top of the SchedulerIO
effect for concurrent logging.
Single Threaded Scheduler
schedulePure :: Eff (InterruptableProcess '[Logs, LogWriterReader PureLogWriter]) a -> Either (ExitReason NoRecovery) a Source #
Like scheduleIO
but pure. The yield
effect is just return ()
.
schedulePure == runIdentity .
scheduleM
(Identity . run) (return ())
Since: 0.3.0.2
defaultMainSingleThreaded :: HasCallStack => Eff (InterruptableProcess LoggingAndIo) () -> IO () Source #
Execute a Process
using scheduleM
on top of Lift
IO
and withLogging
String
effects.
Utilities
Logging Effect
module Control.Eff.Log
Log Writer
Asynchronous
module Control.Eff.LogWriter.Async
Console
File
module Control.Eff.LogWriter.File
UDP
module Control.Eff.LogWriter.UDP
Non-IO Log Message Capturing
Debug.Trace
Generic IO
module Control.Eff.LogWriter.IO
Unix Domain Socket
Preventing Space Leaks
module Control.Eff.Loop