Reliable channels
VAR q := {} status : (K + Null) := ok down := false
APROC Put(m) = << q := q + {m}; status := nil >>
APROC Get() -> M = << VAR m | m = q.head => q := q.tail; IF q = {} => status := ok [*] SKIP FI; RET m >>
APROC GetAck() -> K = << VAR k | k = status => status := ok; RET k >>
APROC Crash() = down := true
APROC Recover() = down := false
THREAD Lose() = DO % internal action
<< down =>
IF VAR q1, q2, m | q = q1 + {m} + q2 =>
q := q1 + q2;IF q2 = {} => status := lost[*] SKIP FI
[*] status := lost
FI >>
Can be down and lose messages, has ack-s