OxL Reference

v4_concurrency.oxl

V.4 with local stand-ins for the services (rpc is stage 3)

oxl✓ checked in CI
// 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<Order>; recs: List<str> }
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<Order> | Timeout  time {
  sleep(20ms)
  [Order{ total: 100 }, Order{ total: 250 }]
}
fn forUser(id: UserId) -> List<str> | 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<Job>, results: Sender<Report>) -> () | 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<Job>(cap: 4)
  let (rtx, rrx) = chan<Report>(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}")
}

Download

Source: examples/v4_concurrency.oxl