extensible-effects-concurrent-0.3.0.1: Message passing concurrency as extensible-effect

Safe HaskellNone
LanguageHaskell2010

Control.Eff.Concurrent.Api.Server

Contents

Description

Functions to implement Api servers.

Synopsis

Api Server

serve :: forall r q p. (Typeable p, SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> ApiHandler p r -> Eff r () Source #

Receive and process incoming requests until the process exits, using an ApiHandler.

data ApiHandler p r where Source #

A record of callbacks, handling requests sent to a server Process, all belonging to a specific Api family instance.

Constructors

ApiHandler :: {..} -> ApiHandler p r 

Fields

ApiHandler default callbacks

unhandledCallError :: forall p x r q. (Show (Api p (Synchronous x)), Typeable p, HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Api p (Synchronous x) -> (x -> Eff r ()) -> Eff r () Source #

A default handler to use in _handleCall in ApiHandler. It will call raiseError with a nice error message.

unhandledCastError :: forall p r q. (Show (Api p Asynchronous), Typeable p, HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Api p Asynchronous -> Eff r () Source #

A default handler to use in _handleCast in ApiHandler. It will call raiseError with a nice error message.

defaultTermination :: forall q r. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Maybe String -> Eff r () Source #

Exit the process either normally of the error message is Nothing or with exitWithError otherwise.

Multi Api Server

serveBoth :: forall r q p1 p2. (Typeable p1, Typeable p2, SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> ApiHandler p1 r -> ApiHandler p2 r -> Eff r () Source #

serve two ApiHandlers at once. The first handler is used for termination handling.

serve3 :: forall r q p1 p2 p3. (Typeable p1, Typeable p2, Typeable p3, SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> ApiHandler p1 r -> ApiHandler p2 r -> ApiHandler p3 r -> Eff r () Source #

serve three ApiHandlers at once. The first handler is used for termination handling.

tryApiHandler :: forall r q p. (Typeable p, SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> ApiHandler p r -> Dynamic -> Eff (Exc UnhandledRequest ': r) () Source #

The basic building block of the combination of ApiHandlers is this function, which can not only be passed to receiveLoop, but also throws an UnhandledRequest exception if requestFromDynamic failed, such that multiple invokation of this function for different ApiHandlers can be tried, by using catchUnhandled.

tryApiHandler px handlers1 message
  `catchUnhandled`
tryApiHandler px handlers2
  `catchUnhandled`
tryApiHandler px handlers3

data UnhandledRequest Source #

An exception that is used by the mechanism that chains together multiple different ApiHandler allowing a single process to implement multiple Apis. This exception is thrown by requestFromDynamic. This exception can be caught with catchUnhandled, this way, several distinct ApiHandler can be tried until one fits or until the exitUnhandled is invoked.

catchUnhandled :: forall r a. (Member (Exc UnhandledRequest) r, HasCallStack) => Eff r a -> (Dynamic -> Eff r a) -> Eff r a Source #

If requestFromDynamic failes to cast the message to a Request for a certain ApiHandler it throws an UnhandledRequest exception. That exception is caught by this function and the raw message is given to the handler function. This is the basis for chaining ApiHandlers.

ensureAllHandled :: forall r q. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Eff (Exc UnhandledRequest ': r) () -> Eff r () Source #

Catch UnhandledRequests and terminate the process with an error, if necessary.

requestFromDynamic :: forall r a. (HasCallStack, Typeable a, Member (Exc UnhandledRequest) r) => Dynamic -> Eff r a Source #

Cast a Dynamic value, and if that fails, throw an UnhandledRequest error.

exitUnhandled :: forall r q. (SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> Dynamic -> Eff r () Source #

If an incoming message could not be casted to a Request corresponding to an ApiHandler (e.g. with requestFromDynamic) one should use this function to exit the process with a corresponding error.