V.4 Chains and concurrency
const PROFILE_DEADLINE = 300ms
// A chain: it is either executed entirely or returns the first unhandled error
fn profilePage(id: UserId) -> Page | NotFound | NetError net {
await Users.get(id) // step 1: rpc; on NotFound the chain is interrupted
-> (Orders.recentFor(it.id), Recs.forUser(it.id)) // step 2: a tuple step = two requests in parallel; it is the result of step 1
-> (orders, recs) => Page{ orders, recs } // step 3: a lambda destructures the tuple
!> Timeout => Page.empty() // on a timeout of any step to the left — an empty page
within PROFILE_DEADLINE // a common deadline for the whole chain
}
fn crawl(urls: List<Url>) -> List<Doc> | HttpError | NetError net {
// Task.of defers the call; all starts all tasks in parallel
// and cancels the rest on the first error
let pages = all(urls.map(u => Task.of { Http.get(u) }))?
pages.map(.toDoc()) // .toDoc() is shorthand for p => p.toDoc()
}
// A channel: read jobs while the senders are alive, and send reports
fn worker(jobs: Receiver<Job>, results: Sender<Report>) -> () | Closed net {
while let job? = jobs.recv().ok() { // job? is the "not none" pattern; the loop ends when the channel is closed
results.send(process(job))? // send waits if the buffer of results is full
}
}Source: docs/spec/oxl-standard.en.md