OxL Справочник OxL
РусскийEnglish

V.4 Цепочки и конкурентность

oxl
const PROFILE_DEADLINE = 300ms

// Цепочка: либо выполняется целиком, либо возвращает первую необработанную ошибку
fn profilePage(id: UserId) -> Page | NotFound | NetError  net {
  await Users.get(id)                                       // шаг 1: rpc; при NotFound цепочка прерывается
    -> (Orders.recentFor(it.id), Recs.forUser(it.id))       // шаг 2: шаг-кортеж = два запроса параллельно; it — результат шага 1
    -> (orders, recs) => Page{ orders, recs }               // шаг 3: лямбда разбирает кортеж
    !> Timeout => Page.empty()                              // при таймауте любого шага слева — пустая страница
    within PROFILE_DEADLINE                                 // общий дедлайн на всю цепочку
}

fn crawl(urls: List<Url>) -> List<Doc> | HttpError | NetError  net {
  // Task.of откладывает вызов; all запускает все задачи параллельно
  // и отменяет остальные при первой ошибке
  let pages = all(urls.map(u => Task.of { Http.get(u) }))?
  pages.map(.toDoc())                 // .toDoc() — сокращение для p => p.toDoc()
}

// Канал: читаем задания, пока отправители живы, и отправляем отчёты
fn worker(jobs: Receiver<Job>, results: Sender<Report>) -> () | Closed  net {
  while let job? = jobs.recv().ok() { // job? — образец «не none»; цикл кончается, когда канал закрыт
    results.send(process(job))?       // send ждёт, если буфер results заполнен
  }
}

Исходник: docs/spec/oxl-standard.md