diff --git a/en/api/@connectum/events/functions/createBroadcastSubscribers.md b/en/api/@connectum/events/functions/createBroadcastSubscribers.md index 35d64130..e726f16a 100644 --- a/en/api/@connectum/events/functions/createBroadcastSubscribers.md +++ b/en/api/@connectum/events/functions/createBroadcastSubscribers.md @@ -4,7 +4,7 @@ > **createBroadcastSubscribers**(`options`): [`EventBus`](../types/interfaces/EventBus.md) & `EventBusLike`[] -Defined in: [packages/events/src/broadcast.ts:74](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/broadcast.ts#L74) +Defined in: [packages/events/src/broadcast.ts:76](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/broadcast.ts#L76) Build one `EventBus` per reactor (each with its own consumer group) so a single published event fans out to ALL reactors independently. diff --git a/en/api/@connectum/events/interfaces/BroadcastSubscribersOptions.md b/en/api/@connectum/events/interfaces/BroadcastSubscribersOptions.md index da16e248..241592c2 100644 --- a/en/api/@connectum/events/interfaces/BroadcastSubscribersOptions.md +++ b/en/api/@connectum/events/interfaces/BroadcastSubscribersOptions.md @@ -21,6 +21,16 @@ own connection / durable consumer). *** +### drainPublishTimeout? + +> `readonly` `optional` **drainPublishTimeout?**: `number` + +Defined in: [packages/events/src/broadcast.ts:48](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/broadcast.ts#L48) + +Shared per-bus opt-in publish drain budget at `stop()` (ms). Since 1.3.0. + +*** + ### drainTimeout? > `readonly` `optional` **drainTimeout?**: `number` @@ -55,6 +65,6 @@ The independent reactors — each becomes its own EventBus with its own group. > `readonly` `optional` **signal?**: `AbortSignal` -Defined in: [packages/events/src/broadcast.ts:48](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/broadcast.ts#L48) +Defined in: [packages/events/src/broadcast.ts:50](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/broadcast.ts#L50) Shared abort signal for graceful shutdown. diff --git a/en/api/@connectum/events/types/interfaces/EventBus.md b/en/api/@connectum/events/types/interfaces/EventBus.md index 94efc24b..45a7e1c0 100644 --- a/en/api/@connectum/events/types/interfaces/EventBus.md +++ b/en/api/@connectum/events/types/interfaces/EventBus.md @@ -2,7 +2,7 @@ # Interface: EventBus -Defined in: [packages/events/src/types.ts:372](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L372) +Defined in: [packages/events/src/types.ts:399](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L399) EventBus interface -- manages adapter, routes, and middleware @@ -12,7 +12,7 @@ EventBus interface -- manages adapter, routes, and middleware > **publish**\<`Desc`\>(`schema`, `data`, `options?`): `Promise`\<`void`\> -Defined in: [packages/events/src/types.ts:386](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L386) +Defined in: [packages/events/src/types.ts:413](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L413) Publish a typed event @@ -46,7 +46,7 @@ Publish a typed event > **start**(`options?`): `Promise`\<`void`\> -Defined in: [packages/events/src/types.ts:382](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L382) +Defined in: [packages/events/src/types.ts:409](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L409) Start the event bus: connect adapter, set up subscriptions. @@ -74,7 +74,7 @@ shutdown or per-event timeout will abort in-flight processing. > **stop**(): `Promise`\<`void`\> -Defined in: [packages/events/src/types.ts:384](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L384) +Defined in: [packages/events/src/types.ts:411](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L411) Stop the event bus: drain subscriptions, disconnect adapter diff --git a/en/api/@connectum/events/types/interfaces/EventBusOptions.md b/en/api/@connectum/events/types/interfaces/EventBusOptions.md index c90aded1..dcc28568 100644 --- a/en/api/@connectum/events/types/interfaces/EventBusOptions.md +++ b/en/api/@connectum/events/types/interfaces/EventBusOptions.md @@ -18,6 +18,39 @@ Adapter instance (e.g., NatsAdapter, KafkaAdapter, MemoryAdapter) *** +### drainPublishTimeout? + +> `optional` **drainPublishTimeout?**: `number` + +Defined in: [packages/events/src/types.ts:379](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L379) + +Opt-in symmetric publish drain during `stop()`: maximum time in +milliseconds to wait for in-flight `publish()` promises (started BEFORE +`stop()` was called) to settle, before the adapter is disconnected. + +Runs concurrently with the handler drain (`drainTimeout`) — shutdown +waits for the slower of the two, not their sum. Tracked promises carry +a no-op observer, so a publish that settles (even rejects) after the +deadline never becomes an `unhandledRejection`; the caller's own +`publish()` promise is unaffected (rejections still propagate to it). + +NOT covered: publishes issued from inside handlers (including the DLQ +republish) — those are governed by the handler drain and its post-abort +settle window; new `publish()` calls after `stop()` begins are rejected +by the stopping gate (the relay-pattern design is tracked in +https://github.com/Connectum-Framework/connectum/issues/212). + +Budget note: `createServer`'s `shutdown.timeout` bounds the transport +phase, not the shutdown hooks that stop the bus — a large value here +extends total process shutdown accordingly; size it below your +orchestrator's kill grace period. + +Default: `undefined` — disabled: `stop()` behavior is unchanged and +in-flight publishes race the adapter disconnect exactly as before. +`0` (or negative) also disables waiting. Available since 1.3.0. + +*** + ### drainTimeout? > `optional` **drainTimeout?**: `number` @@ -111,7 +144,7 @@ Automatically set when used with `createServer({ eventBus })`. > `optional` **strictTopics?**: `boolean` -Defined in: [packages/events/src/types.ts:366](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L366) +Defined in: [packages/events/src/types.ts:393](https://github.com/Connectum-Framework/connectum/blob/main/packages/events/src/types.ts#L393) Reject a `publish()` whose topic cannot be resolved instead of silently falling back to the message `typeName`. diff --git a/en/packages/events.md b/en/packages/events.md index b49e3a71..07281eb5 100644 --- a/en/packages/events.md +++ b/en/packages/events.md @@ -134,6 +134,7 @@ function createEventBus(options: EventBusOptions): EventBus & EventBusLike; | `signal` | `AbortSignal` | `undefined` | Abort signal for graceful shutdown | | `handlerTimeout` | `number` | `30000` | Timeout in ms for event handler execution | | `drainTimeout` | `number` | `30000` | Max ms to wait for in-flight handlers during `stop()` | +| `drainPublishTimeout` | `number` | `undefined` | Opt-in: max ms to wait for in-flight `publish()` promises during `stop()`, before the adapter disconnects. Runs concurrently with the handler drain (slower-of, never the sum). `undefined`/`0` = disabled. Available since 1.3.0 | | `middleware` | `MiddlewareConfig` | `undefined` | Middleware configuration (retry, DLQ, custom) | | `publishes` | `DescService[]` | `[]` | Event service descriptors this process publishes to (publisher-only, no subscription) | | `strictTopics` | `boolean` | `false` | Throw on an unresolved publish topic instead of silently falling back to the message `typeName`. Available since 1.1.0. | @@ -263,6 +264,7 @@ await Promise.all(buses.map((bus) => bus.start())); | `reactors` | `BroadcastReactor[]` | *required* | The independent reactors -- each becomes its own `EventBus` with its own group | | `handlerTimeout` | `number` | `30000` | Shared per-bus handler timeout in ms | | `drainTimeout` | `number` | `30000` | Shared per-bus drain timeout in ms | +| `drainPublishTimeout` | `number` | `undefined` | Shared per-bus opt-in publish drain budget at `stop()` (ms). Available since 1.3.0 | | `signal` | `AbortSignal` | `undefined` | Shared abort signal for graceful shutdown | ### `BroadcastReactor` @@ -337,7 +339,7 @@ await bus.stop(); Two related boundaries: - **Publishing from a draining handler is rejected** — once `stop()` begins, `publish()` throws, including from handlers that are still draining. Relay topologies (consume → transform → publish) lose the in-flight tail at shutdown; the design discussion is tracked in [connectum#212](https://github.com/Connectum-Framework/connectum/issues/212). -- **An opt-in symmetric publish drain** (`drainPublishTimeout`) is planned — tracked in [connectum#196](https://github.com/Connectum-Framework/connectum/issues/196). +- **An opt-in symmetric publish drain** ships since 1.3.0: set `drainPublishTimeout` and `stop()` waits (up to that budget, concurrently with the handler drain) for publishes started before `stop()` to settle, before the adapter disconnects. A post-deadline settlement never becomes an `unhandledRejection`. Publishes issued from draining handlers stay uncovered (the stopping gate; design tracked in [connectum#212](https://github.com/Connectum-Framework/connectum/issues/212)). Note: `createServer`'s `shutdown.timeout` does not bound the bus-stopping hook — size the budget below your orchestrator's kill grace. ## Exports Summary