0 | module IO.Async.Service
2 | import Data.Linear.Deferred
4 | import IO.Async.Channel
19 | record Service (e : Type) (errs : List Type) (req : Type) (resp : req -> Type) where
21 | constructor MkService
22 | close : Async e [] ()
23 | send : (r : req) -> Async e errs (resp r)
26 | Resource (Async e) (Service e es a p) where cleanup = close
28 | record Req (errs : List Type) (a : Type) (p : a -> Type) where
31 | resp : Once World (Result errs $
p req)
33 | parameters {0 a,e : Type}
34 | {default 100 capacity : Nat}
42 | -> (s -> (v : a) -> Async e es (s, p v))
43 | -> Async e fs (Service e es a p)
44 | service ini conv = do
45 | chnl <- channelOf (Req es a p) capacity
46 | fbr <- start (go ini chnl)
47 | pure $
MkService (close chnl >> wait fbr) (snd chnl)
51 | go : s -> Channel (Req es a p) -> Async e [] ()
53 | Just (R req o) <- receive chnl | Nothing => pure ()
54 | attempt (conv st req) >>= \case
55 | Left x => putOnce o (Left x) >> go st chnl
56 | Right (st2,r) => putOnce o (Right r) >> go st2 chnl
58 | snd : Channel (Req es a p) -> (v : a) -> Async e es (p v)
60 | o <- onceOf (Result es $
p v)
61 | send chnl (R v o) >>= \case
62 | Closed => canceled >> never
63 | _ => awaitOnce o >>= either fail pure
68 | stateless : ((v : a) -> Async e es (p v)) -> Async e fs (Service e es a p)
69 | stateless f = service () $
\_,v => ((),) <$> f v
74 | stateful : s -> (s -> (v : a) -> (s, p v)) -> Async e fs (Service e es a p)
75 | stateful ini conv = service ini $
\x,st => pure $
conv x st