// V.4 with local stand-ins for the services (rpc is stage 3) const PROFILE_DEADLINE = 300ms type UserId = distinct i64 @error data NotFound { id: i64 } data User { id: UserId; name: str } data Order { total: i64 } data Page { orders: List; recs: List } impl Page { static fn empty() -> Page => Page{ orders: [], recs: [] } } fn getUser(id: UserId) -> User | NotFound | Timeout time { sleep(5ms) if id.raw == 0 { fail NotFound{ id: 0 } } User{ id, name: "ann" } } fn recentFor(id: UserId) -> List | Timeout time { sleep(20ms) [Order{ total: 100 }, Order{ total: 250 }] } fn forUser(id: UserId) -> List | Timeout time { sleep(if id.raw == 2 { 2s } else { 10ms }) ["book", "pen"] } fn profilePage(id: UserId) -> Page | NotFound | Timeout time { await getUser(id) -> (recentFor(it.id), forUser(it.id)) -> (orders, recs) => Page{ orders, recs } !> Timeout => Page.empty() within PROFILE_DEADLINE } data Job { n: i64 } data Report { n: i64; sq: i64 } fn process(j: Job) -> Report => Report{ n: j.n, sq: j.n * j.n } fn worker(jobs: Receiver, results: Sender) -> () | Closed { while let job? = jobs.recv().ok() { results.send(process(job))? } } fn main() io, time { match profilePage(UserId(1)) { Page p => print("orders {p.orders.len()} recs {p.recs.len()}") NotFound => print("not found") Timeout => print("timeout") } match profilePage(UserId(0)) { NotFound => print("not found") _ => print("?") } let (jtx, jrx) = chan(cap: 4) let (rtx, rrx) = chan(cap: 4) let total = scope { spawn worker(jrx, rtx) for i in 1..=5 { _ = jtx.send(Job{ n: i }) } drop(jtx) var sum = 0 while let r? = rrx.recv().ok() { sum += r.sq } sum } print("sum of squares {total}") }