| 1 | /** |
| 2 | * Register effects that should have one active owner in an Effect cluster. |
| 3 | * |
| 4 | * `Singleton.make` wraps `Sharding.registerSingleton` in a `Layer`. When the |
| 5 | * local runner owns the shard for the singleton's name and shard group, |
| 6 | * sharding starts the effect; when ownership moves or the layer scope closes, |
| 7 | * the running fiber is interrupted and the registration is removed. |
| 8 | * |
| 9 | * @stability unstable |
| 10 | * @since 4.0.0 |
| 11 | */ |
| 12 | import * as Effect from "../Effect.ts" |
| 13 | import * as Layer from "../Layer.ts" |
| 14 | import type { Scope } from "../Scope.ts" |
| 15 | import { Sharding } from "./Sharding.ts" |
| 16 | |
| 17 | /** |
| 18 | * Creates a layer that registers a singleton effect with `Sharding` under the |
| 19 | * specified name and optional shard group. |
| 20 | * |
| 21 | * **When to use** |
| 22 | * |
| 23 | * Use to register a cluster-wide background effect as a `Layer`, so the effect |
| 24 | * is started only by the runner that currently owns the singleton's shard. |
| 25 | * |
| 26 | * **Details** |
| 27 | * |
| 28 | * The returned layer requires `Sharding` and the services needed by `run`, |
| 29 | * except for `Scope`. The registration is scoped to the layer; closing the |
| 30 | * layer removes the singleton registration and stops the singleton fiber if it |
| 31 | * is running. |
| 32 | * |
| 33 | * **Gotchas** |
| 34 | * |
| 35 | * - Registering the same singleton name in the same shard group more than once |
| 36 | * dies during registration. |
| 37 | * - A `run` effect that completes normally is kept alive until the registration |
| 38 | * scope closes or shard ownership moves. |
| 39 | * - Failures from `run` are converted to defects, so handle expected failures |
| 40 | * inside `run` when the singleton should keep running. |
| 41 | * |
| 42 | * @see {@link Sharding} for the lower-level service that registers singletons and manages shard ownership |
| 43 | * |
| 44 | * @stability unstable |
| 45 | * @category constructors |
| 46 | * @since 4.0.0 |
| 47 | */ |
| 48 | export const make = <E, R>( |
| 49 | name: string, |
| 50 | run: Effect.Effect<void, E, R>, |
| 51 | options?: { |
| 52 | readonly shardGroup?: string | undefined |
| 53 | } |
| 54 | ): Layer.Layer<never, never, Sharding | Exclude<R, Scope>> => |
| 55 | Layer.effectDiscard(Effect.gen(function*() { |
| 56 | const sharding = yield* Sharding |
| 57 | yield* sharding.registerSingleton(name, run, options) |
| 58 | })) |