diff --git a/specification.json b/specification.json index 573d6190..f79c8769 100644 --- a/specification.json +++ b/specification.json @@ -31,7 +31,7 @@ { "id": "Requirement 1.1.2.4", "machine_id": "requirement_1_1_2_4", - "content": "The `API` SHOULD provide functions to set a provider and wait for the `initialize` function to complete or abnormally terminate.", + "content": "The `API` SHOULD provide functions to set a provider and wait for `initialize` to terminate and its resulting lifecycle event to be processed.", "RFC 2119 keyword": "SHOULD", "children": [] }, @@ -582,14 +582,14 @@ { "id": "Requirement 2.8.2", "machine_id": "requirement_2_8_2", - "content": "The provider MUST emit `PROVIDER_READY` if its `initialize` function terminates normally.", + "content": "The provider MUST emit `PROVIDER_READY` before its `initialize` function terminates normally.", "RFC 2119 keyword": "MUST", "children": [] }, { "id": "Requirement 2.8.3", "machine_id": "requirement_2_8_3", - "content": "The provider MUST emit `PROVIDER_ERROR` if its `initialize` function terminates abnormally.", + "content": "The provider MUST emit `PROVIDER_ERROR` before its `initialize` function terminates abnormally.", "RFC 2119 keyword": "MUST", "children": [] }, diff --git a/specification/appendix-e-migrations.md b/specification/appendix-e-migrations.md index 119da1b5..00c3ba3a 100644 --- a/specification/appendix-e-migrations.md +++ b/specification/appendix-e-migrations.md @@ -41,8 +41,7 @@ Providers with no `initialize` function are handled per [Condition 2.8.5](./sect If `initialize` performs setup synchronously and returns when ready, emit `PROVIDER_READY` immediately before returning (or `PROVIDER_ERROR` before throwing). **Event-driven initialization.** -If setup completes asynchronously (e.g. the underlying vendor SDK signals readiness via its own event), forward that signal as `PROVIDER_READY`. -`initialize` may return before the event is emitted; the SDK treats the return as a synchronization signal only. +If setup completes asynchronously (e.g. the underlying vendor SDK signals readiness via its own event), keep `initialize` pending until that signal arrives, emit the corresponding `PROVIDER_READY` or `PROVIDER_ERROR` event, then return or throw. **Context reconciliation.** The provider now owns the coalescing behavior previously handled by the SDK. @@ -51,7 +50,7 @@ If `on context changed` may be invoked simultaneously or in quick succession, em #### Anti-patterns - Do not emit `PROVIDER_READY` before initialization work is complete. -- Do not rely on `initialize`'s return being observed by the SDK for status transitions; it is a synchronization signal only. +- Do not terminate `initialize` before emitting the corresponding `PROVIDER_READY` or `PROVIDER_ERROR` event. ### For SDK authors diff --git a/specification/sections/01-flag-evaluation.md b/specification/sections/01-flag-evaluation.md index 035dfcb7..3d316572 100644 --- a/specification/sections/01-flag-evaluation.md +++ b/specification/sections/01-flag-evaluation.md @@ -57,9 +57,11 @@ see [shutdown](./02-providers.md#25-shutdown), [setting a provider](#setting-a-p #### Requirement 1.1.2.4 -> The `API` **SHOULD** provide functions to set a provider and wait for the `initialize` function to complete or abnormally terminate. +> The `API` **SHOULD** provide functions to set a provider and wait for `initialize` to terminate and its resulting lifecycle event to be processed. This function not only sets the provider, but ensures that the provider is ready (or in error) before returning or settling. +The SDK waits for both `initialize` termination and the status update from the resulting `PROVIDER_READY` or `PROVIDER_ERROR` event (see [provider events](./05-events.md#51-provider-events)) before settling. +Application event handlers need not complete before the function returns or settles. ```java // default provider diff --git a/specification/sections/02-providers.md b/specification/sections/02-providers.md index 02bdeac2..81a2b338 100644 --- a/specification/sections/02-providers.md +++ b/specification/sections/02-providers.md @@ -340,7 +340,8 @@ Providers signal all state transitions by emitting the appropriate event; the SD Shutdown is the exception: the SDK initiates the `shutdown` call and infers the `NOT_READY` transition itself, so no event from the provider is required (see [Requirement 1.7.6](./01-flag-evaluation.md#requirement-176)). Providers that do not define an `initialize` function are not required to emit events for initialization; see Condition 2.8.5. -Requirements 2.8.1-2.8.4 apply only to providers that define lifecycle methods. +Requirement 2.8.1 applies to all provider status transitions; Requirements 2.8.2-2.8.4 apply only when the provider defines the corresponding lifecycle method. +Where practical, SDKs should couple lifecycle methods with event support so providers defining lifecycle methods can emit the required events. see: [provider lifecycle management](./01-flag-evaluation.md#17-provider-lifecycle-management), [provider events](./05-events.md#51-provider-events) @@ -355,17 +356,20 @@ see: [provider events](./05-events.md#51-provider-events), [provider event types #### Requirement 2.8.2 -> The provider **MUST** emit `PROVIDER_READY` if its `initialize` function terminates normally. +> The provider **MUST** emit `PROVIDER_READY` before its `initialize` function terminates normally. + +The provider is the sole source of this event; the SDK does not synthesize it based on the return of `initialize`. + +see: [Requirement 1.1.2.4](./01-flag-evaluation.md#requirement-1124) #### Requirement 2.8.3 -> The provider **MUST** emit `PROVIDER_ERROR` if its `initialize` function terminates abnormally. +> The provider **MUST** emit `PROVIDER_ERROR` before its `initialize` function terminates abnormally. +The provider is the sole source of this event; the SDK does not synthesize it based on the return of `initialize`. If the error is irrecoverable, the error code must indicate `PROVIDER_FATAL`. -The provider is the sole source of this event; the SDK does not synthesize `PROVIDER_ERROR` on abnormal termination, even if `initialize` throws or returns an error. -The `initialize` return (or thrown error) is treated by the SDK as a synchronization signal only (e.g. to unblock `setProviderAndWait`); the status transition to `ERROR` or `FATAL` occurs only when the SDK receives the provider-emitted `PROVIDER_ERROR`. -see: [error codes](../types.md#error-code) +see: [error codes](../types.md#error-code), [Requirement 1.1.2.4](./01-flag-evaluation.md#requirement-1124) #### Requirement 2.8.4 diff --git a/specification/sections/05-events.md b/specification/sections/05-events.md index a205b9b6..82fdea7b 100644 --- a/specification/sections/05-events.md +++ b/specification/sections/05-events.md @@ -35,7 +35,8 @@ see: [domain](../glossary.md#domain) Providers must emit events to signal all state transitions, including those resulting from lifecycle methods (initialize, reconciliation). The SDK derives provider status from these events. -Providers without lifecycle methods or an event emission mechanism cannot emit events by design; see [Condition 2.8.5](./02-providers.md#condition-285). +Providers can emit spontaneous events without defining lifecycle methods. +Providers that define `initialize` or `on context changed` must support event emission; see [provider status](./02-providers.md#28-provider-status). If available, native event-emitter or observable/observer language constructs can be used.