| 1 | /** |
| 2 | * Single-process cluster layer for durable entities and workflows. It wires |
| 3 | * `Sharding` with no-op runner communication, no-op runner health checks, |
| 4 | * SQL-backed message storage, environment-based sharding configuration, and |
| 5 | * either SQL-backed or in-memory runner storage. |
| 6 | * |
| 7 | * This layer is meant for local, embedded, or small single-node setups where the |
| 8 | * process handles all cluster work itself. It still requires a SQL client |
| 9 | * because mailbox messages and replies are stored in SQL. |
| 10 | * |
| 11 | * @stability unstable |
| 12 | * @since 4.0.0 |
| 13 | */ |
| 14 | import * as Layer from "effect/Layer" |
| 15 | import type { ConfigError } from "../Config.ts" |
| 16 | import type * as Crypto from "../Crypto.ts" |
| 17 | import type * as SqlClient from "../sql/SqlClient.ts" |
| 18 | import type * as MessageStorage from "./MessageStorage.ts" |
| 19 | import * as RunnerHealth from "./RunnerHealth.ts" |
| 20 | import * as Runners from "./Runners.ts" |
| 21 | import * as RunnerStorage from "./RunnerStorage.ts" |
| 22 | import * as Sharding from "./Sharding.ts" |
| 23 | import * as ShardingConfig from "./ShardingConfig.ts" |
| 24 | import * as SqlMessageStorage from "./SqlMessageStorage.ts" |
| 25 | import * as SqlRunnerStorage from "./SqlRunnerStorage.ts" |
| 26 | |
| 27 | /** |
| 28 | * Provides a SQL-backed single-node cluster for running durable |
| 29 | * entities and workflows. |
| 30 | * |
| 31 | * **When to use** |
| 32 | * |
| 33 | * Use to run durable cluster entities and workflows in a local, embedded, or |
| 34 | * small single-node process while keeping mailbox and reply state in SQL. |
| 35 | * |
| 36 | * **Details** |
| 37 | * |
| 38 | * The layer provides `Sharding`, `Runners`, and `MessageStorage`. It loads |
| 39 | * `ShardingConfig` from environment variables and overlays |
| 40 | * `options.shardingConfig` when provided. Message storage is always SQL-backed; |
| 41 | * runner storage is SQL-backed by default and switches to in-memory storage |
| 42 | * when `runnerStorage` is set to `"memory"`. |
| 43 | * |
| 44 | * **Gotchas** |
| 45 | * |
| 46 | * - Even when `runnerStorage` is `"memory"`, message storage remains |
| 47 | * SQL-backed, so callers must still provide `SqlClient` and `Crypto.Crypto` |
| 48 | * (used to hash over-length message deduplication keys). |
| 49 | * - Runner communication and runner health are no-op services, so this layer is |
| 50 | * for single-process use rather than multi-runner coordination. |
| 51 | * |
| 52 | * @see {@link ShardingConfig.layerFromEnv} for loading environment configuration before applying `shardingConfig` overrides |
| 53 | * @see {@link SqlMessageStorage.layer} for the SQL-backed message storage that this layer provides |
| 54 | * @see {@link SqlRunnerStorage.layer} for the default SQL-backed runner storage selected when `runnerStorage` is omitted or `"sql"` |
| 55 | * @see {@link RunnerStorage.layerMemory} for the in-memory runner storage selected by `runnerStorage: "memory"` |
| 56 | * |
| 57 | * @stability unstable |
| 58 | * @category layers |
| 59 | * @since 4.0.0 |
| 60 | */ |
| 61 | export const layer = (options?: { |
| 62 | readonly shardingConfig?: Partial<ShardingConfig.ShardingConfig["Service"]> | undefined |
| 63 | readonly runnerStorage?: "memory" | "sql" | undefined |
| 64 | }): Layer.Layer< |
| 65 | | Sharding.Sharding |
| 66 | | Runners.Runners |
| 67 | | MessageStorage.MessageStorage, |
| 68 | ConfigError, |
| 69 | SqlClient.SqlClient | Crypto.Crypto |
| 70 | > => |
| 71 | Sharding.layer.pipe( |
| 72 | Layer.provideMerge(Runners.layerNoop), |
| 73 | Layer.provideMerge(SqlMessageStorage.layer), |
| 74 | Layer.provide([ |
| 75 | options?.runnerStorage === "memory" ? RunnerStorage.layerMemory : Layer.orDie(SqlRunnerStorage.layer), |
| 76 | RunnerHealth.layerNoop |
| 77 | ]), |
| 78 | Layer.provide(ShardingConfig.layerFromEnv(options?.shardingConfig)) |
| 79 | ) |