GenServer
Client-Server Model
See: Erlang gen_server Behaviour
GenServer Typeclass
class GenServer req rep st | req -> rep, rep -> st, st -> req where
handleCall :: HandleCall req rep st
handleCast :: HandleCast req rep st
Server Example
module Demo.Server
( start
, inc
, dec
, query
) where
import Prelude
import Control.Behaviour.GenServer
( class GenServer
, HandleCall
, HandleCast
, Init
, startLinkWith
, initOk
, call
, cast
, noReply
, reply
, shutdown
)
import System.IO (println)
data Request = Inc | Dec | Query
data Reply = QueryResult Integer
data State = State Integer
name :: Atom
name = :server
start :: Process Pid
start = startLinkWith name (init 20)
-----------------------------------------------------------------------------
-- | Server API
-----------------------------------------------------------------------------
inc :: Process ()
inc = cast name Inc
dec :: Process ()
dec = cast name Dec
query :: Process Integer
query = do
QueryResult i <- call name Query
return i
-----------------------------------------------------------------------------
-- | Server callbacks
-----------------------------------------------------------------------------
instance GenServer Request Reply State where
handleCall = handleCall
handleCast = handleCast
init :: Integer -> Init Request State
init n = initOk (State n)
handleCall :: HandleCall Request Reply State
handleCall Query _from (State i) = do
println "Call: Query"
reply (QueryResult i) (State i)
handleCall _req _from st =
shutdown :badRequest st
handleCast :: HandleCast Request Reply State
handleCast Inc (State n) = do
println "Cast: Inc"
noReply $ State (n+1)
handleCast Dec (State n) = do
println "Cast: Dec"
noReply $ State (n-1)
handleCast _ st = noReply st
Start a Server process
-- | Start a standalone Server process.
start :: forall req rep st. GenServer req rep st => (Init req st) -> Process Pid
startWith :: forall req rep st. GenServer req rep st => Name -> (Init req st) -> Process Pid
-- | Start a Server process as part of a supervision tree.
startLink :: forall req rep st. GenServer req rep st => (Init req st) -> Process Pid
startLinkWith :: forall req rep st. GenServer req rep st => Name -> (Init req st) -> Process Pid
Init callback
-- | Init Result
data InitResult req st
= InitOk st (Maybe (Action req))
-- ^ {ok, State}
| InitIgnore
-- ^ ignore
| InitStop ExitReason
-- ^ {stop, Reason}
-- | Init callback
type Init req st = Process (InitResult req st)
HandleCall and HandleCast
-- | HandleCall callback
type HandleCall req rep st
= req -> From -> st -> Process (Reply req rep st)
-- | HandleCast callback
type HandleCast req rep st
= req -> st -> Process (Reply req rep st)
Client APIs
-- | Synchronous call to the server process.
call :: forall req rep. Name -> req -> Process rep
-- | Sends an asynchronous request to the server process.
cast :: forall req. Name -> req -> Process ()
当前内容版权归 hamler-lang 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 hamler-lang .