12.6 Распределённые вычисления
let byRegion = cluster.shards(db.Order)
.map(o => (o.region, o.total)) // выполняется на владельцах шардов
.reduceBy(.0, (a, b) => a + b) // частичная агрегация, затем слияние
within REPORT_DEADLINE
cluster.leader("nightly-report") { every(REPORT_PERIOD) { buildReport() } }
cluster.lock("user:{uid}", ttl: LOCK_TTL) { migrateUser(uid) }cluster.shards(src)— для шардированных таблиц и акторов;mapвыполняется рядом с данными, функция ДОЛЖНА быть передаваемой (§7.3).
Определяется реализацией. Вычисление рядом с данными (D-8055; DIV-015; D-4804, D-4899). Необязательная возможность: цепочка
cluster.shards(src).map(…).reduceBy(…) within d. Эта реализация её не строит (нужны переносимое замыкание и scatter-gather); доступноcluster.shards()— список групп шардовShardInfo. Запрос по всем шардам выполняется ORM (§12.8). Возможное расширение — после 1.0.
cluster.leader(name) { … }регистрирует задачу-лидера и сразу возвращает управление. На узлах, роли которых содержатruns leader(name), узлы выбирают одного лидера, и блок выполняется на нём в фоновом scope; при отказе лидера блок запускается на другом узле. На остальных узлах вызов ничего не делает.cluster.lock(key, ttl) { … }— распределённая блокировка с арендой. Тип вызова —T | LockTimeout | NetError, гдеT— тип блока:LockTimeout— блокировку не удалось получить за срок ожидания;NetError(Unavailable) — координатор был недоступен в последней попытке ожидания. То же дляcluster.lockFenced. Игнорировать результат — ошибкаunhandled-error(D-8052; D-7520).cluster.ids.next() -> u64— уникальный монотонный по узлу идентификатор;cluster.now()— гибридные логические часы (§17).cluster.self.hasRole(r) -> bool— есть ли у текущего узла рольr.@near(expr)на функции выполняет её на узле, где находится актор или шардexpr.
См. также
Исходник: docs/spec/oxl-standard.md