completion.bend
bend-kit-http@0.32.0.0 · 43 lines · 0 definitions
1# Copied response completion data; successful host writes do not prove peer receipt.
2import Base
3
4type Outcome is Data:
5 HostAccepted{}
6 WriteFailed{code: U32, message: String}
7 IncompleteResponse{}
8
9type Completion<-D: Data> is Data:
10 Completion{payload: D, status: U32, outcome: Outcome}
11
12# Consumed inline while the admitted operation is still held.
13# Supported receipts capture Data only through receipt's typed factory and a
14# closed callback. Never hide affine dependencies in a disposable receipt.
15type Receipt is Type:
16 Unobserved{}
17 Observed{send: U32 -> Outcome -> IO(Unit)}
18
19def receipt.send(~D: Data, payload: D, +channel: Chan(Completion<D>), status: U32, outcome: Outcome) -> IO(Unit):
20 do IO<Unit>:
21 sent : Result<&1, &1, Completion<D>, Unit> <- Chan.send(Completion<D>, channel, Completion{payload, status, outcome})
22 return Unit{}
23
24def receipt(~D: Data, ~done: Completion<D> -> IO(Unit), payload: D) -> Receipt:
25 Observed{status => outcome => done(Completion{payload, status, outcome})}
26
27# The observer owns IO.join/explicit close, including when it receives later.
28# Closing before reception is disposal; it never carries affine resources.
29def open(~D: Data, payload: D) -> IO(Receipt & Chan(Completion<D>)):
30 do IO<Receipt & Chan(Completion<D>)>:
31 +channel : Chan(Completion<D>) <- Chan.new(Completion<D>, 1)
32 return (Observed{status => outcome => receipt.send(~D, payload, channel, status, outcome)}, channel)
33
34def report(receipt: Receipt, status: U32, outcome: Outcome) -> IO(Unit):
35 match receipt:
36 case Unobserved{}:
37 IO.pure(Unit, Unit{})
38 case Observed{send}:
39 send(status, outcome)
40
41# Explicit absence of a configured observer performs no logging or allocation.
42def ignore(status: U32, outcome: Outcome) -> IO(Unit):
43 IO.pure(Unit, Unit{})