tur/session
standard session-type protocol patterns for typed channels.
Reusable protocol templates built on the core session primitives.
Since: Phase B1
SessionPeer
(defopaque SessionPeer :ptr<void>)
handle to a running session peer (see session-spawn).
Compiled: a heap pthread_t. Interpreted: the peer fiber's future. Consumed exactly once, by session-join.
Since: turi-session-expansion S2
session-spawn
(session-spawn [^fat f :(fn [] nil)] :SessionPeer)
run f as the peer of a session, on a thread or a fiber.
| f | a zero-argument thunk that drives one endpoint to close |
A SessionPeer to hand to session-join once this side has finished its own half of the protocol.
(let [[s r] (make-session (Send int Close))]
(let [t (session-spawn (fn [] (let [[n r] (recv r)] (println n) (close r))))]
(let [s (send s 42)] (close s) (session-join t)))) ; => prints 42
Since: turi-session-expansion S2
session-join
(session-join [t :SessionPeer] :nil)
wait for a session peer started by session-spawn.
| t | the SessionPeer returned by session-spawn; consumed by this call |
nil, once the peer thunk has returned.
(session-join t)
Since: turi-session-expansion S2
echo-server-loop
(echo-server-loop [^linear ch :(Session (Rec self (Branch (Recv int (Send int self)) Close)))] :nil)
serve the echo protocol until the client closes.
| ch | server-side channel with protocol | |
| Session[Rec self (Branch (Recv int (Send int self)) Close)] |
nil -- the function returns after the client sends Close
(session-spawn (fn [] (echo-server-loop server-end)))
Since: SS4
echo-client-call
(echo-client-call [^linear ch :(Session (Rec self (Choose (Send int (Recv int self)) Close))) val :int handler :(-> int nil)] :(Session (Rec self)
send one integer, hand the echo to handler, return the channel.
| ch | client-side channel with protocol | |
| Session[Rec self (Choose (Send int (Recv int self)) Close)] | ||
| val | integer to send and have echoed back | |
| handler | called with the echoed integer |
The channel, back at the recursive EchoClientProto so more calls can be
made -- or (close (choose-right ch)) to end the conversation.
(let [ch (echo-client-call ch 42 (fn [r] (println r)))] ; prints 42 (close (choose-right ch)))
Since: SS4
rpc-call
(rpc-call [^linear ch :(Session (Send int (Recv int Close))) req :int] :int)
perform a single RPC: send request, receive response, close.
| ch | client channel with protocol Session[Send int (Recv int Close)] | |
| req | integer request value to send to the server |
The integer response received from the server. The channel is fully consumed (closed) by this call.
(let [resp (rpc-call ch 21)] (println resp)) ; => 42 (if server doubles the value)
Since: SS4
pubsub-recv-loop
(pubsub-recv-loop [^linear ch :(Session (Recv int (Rec self (Branch (Recv int self) Close)))) handler :(-> int nil)] :nil)
receive messages from a topic until it closes.
| ch | subscriber channel with protocol | |
| Session[Recv int (Rec self (Branch (Recv int self) Close))] | ||
| handler | function called with each received integer message |
nil -- returns after the topic sends the Close branch
(pubsub-recv-loop sub-ch (fn [msg] (println msg)))
Since: SS4
pubsub-recv-loop-inner
(pubsub-recv-loop-inner [^linear ch :(Session (Rec self (Branch (Recv int self) Close))) handler :(-> int nil)] :nil)
inner recursive loop after initial recv.