Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add events #182

Merged
merged 24 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 85 additions & 1 deletion specification.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
{
"id": "Requirement 1.1.5",
"machine_id": "requirement_1_1_5",
"content": "The API MUST provide a function for retrieving the metadata field of the configured `provider`.",
"content": "The `API` MUST provide a function for retrieving the metadata field of the configured `provider`.",
toddbaert marked this conversation as resolved.
Show resolved Hide resolved
"RFC 2119 keyword": "MUST",
"children": []
},
Expand Down Expand Up @@ -629,6 +629,90 @@
"content": "The hook MUST NOT alter the `hook hints` structure.",
"RFC 2119 keyword": "MUST NOT",
"children": []
},
{
"id": "Requirement 5.1.1",
"machine_id": "requirement_5_1_1",
"content": "The `provider` MAY define a mechanism for signaling the occurrence of one of a set of events, including `PROVIDER_READY`, `PROVIDER_ERROR`, `PROVIDER_CONFIGURATION_CHANGED` and `PROVIDER_STALE`, with an `provider event details` payload.",
toddbaert marked this conversation as resolved.
Show resolved Hide resolved
"RFC 2119 keyword": "MAY",
"children": []
},
{
"id": "Requirement 5.1.2",
"machine_id": "requirement_5_1_2",
"content": "When the `provider` signals the occurrence of a particular `event`, the associated `client` and `API` event handlers` MUST run.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.1.3",
"machine_id": "requirement_5_1_3",
"content": "`PROVIDER_ERROR` events SHOULD populate the `provider event details`'s `error message` field.",
"RFC 2119 keyword": "SHOULD",
"children": []
},
{
"id": "Requirement 5.2.1",
"machine_id": "requirement_5_2_1",
"content": "The `client` MUST provide an `addHandler` function for associating callbacks with `provider events`, which accepts an `event type` and a `event handler function`.",
Kavindu-Dodan marked this conversation as resolved.
Show resolved Hide resolved
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.2",
"machine_id": "requirement_5_2_2",
"content": "The `API` MUST provide an `addHandler` function for associating callbacks with `provider events`, which accepts an `event type` and a `event handler function`.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.3",
"machine_id": "requirement_5_2_3",
"content": "The `event details` MUST contain the `client name` associated with the event.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.4",
"machine_id": "requirement_5_2_4",
"content": "The `event handler` function MUST accept a `event details` or `error event metadata` parameter.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.5",
"machine_id": "requirement_5_2_5",
"content": "If the provider's `initialize` function terminates normally, `PROVIDER_READY` handlers MUST run.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.6",
"machine_id": "requirement_5_2_6",
"content": "If the provider's `initialize` function terminates abnormally, `PROVIDER_ERROR` handlers MUST run.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.7",
"machine_id": "requirement_5_2_7",
"content": "`PROVIDER_READY` handlers added after the provider is already in a ready state MUST run immediately.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.8",
"machine_id": "requirement_5_2_8",
"content": "If a `handler functions` terminates abnormally, other event handlers MUST run.",
"RFC 2119 keyword": "MUST",
"children": []
},
{
"id": "Requirement 5.2.9",
"machine_id": "requirement_5_2_9",
"content": "Event handlers MUST persist across `provider` changes.",
"RFC 2119 keyword": "MUST",
"children": []
}
]
}
2 changes: 1 addition & 1 deletion specification/sections/01-flag-evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ See [hooks](./04-hooks.md) for details.

#### Requirement 1.1.5

> The API **MUST** provide a function for retrieving the metadata field of the configured `provider`.
> The `API` **MUST** provide a function for retrieving the metadata field of the configured `provider`.

```typescript
// example provider accessor
Expand Down
2 changes: 1 addition & 1 deletion specification/sections/04-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ val = client.get_boolean_value('my-key', False, evaluation_options={
})
```

See: [Flag evaluation options](./01-flag-evaluation.md#)
see: [Flag evaluation options](./01-flag-evaluation.md#)

#### Requirement 4.5.1

Expand Down
102 changes: 102 additions & 0 deletions specification/sections/05-events.md
toddbaert marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: Events
toddbaert marked this conversation as resolved.
Show resolved Hide resolved
description: Specification defining event semantics
toc_max_heading_level: 4
---

# 5. Events

[![experimental](https://img.shields.io/static/v1?label=Status&message=experimental&color=orange)](https://github.com/open-feature/spec/tree/main/specification#experimental)

## Overview

`Events` allow consumers (_application integrator_, _application author_, _integration author_) to react to state changes in the provider or underlying flag management system, such as flag definition changes, provider readiness, or error conditions. A provider may emit events or run a callback indicating that it received a certain event, optionally providing data associated with that event. Handlers registered on the client are then invoked with this data.
toddbaert marked this conversation as resolved.
Show resolved Hide resolved

Kavindu-Dodan marked this conversation as resolved.
Show resolved Hide resolved
### 5.1. Provider events

#### Requirement 5.1.1

> The `provider` **MAY** define a mechanism for signaling the occurrence of one of a set of events, including `PROVIDER_READY`, `PROVIDER_ERROR`, `PROVIDER_CONFIGURATION_CHANGED` and `PROVIDER_STALE`, with an `provider event details` payload.

If available, native event-emitter or observable/observer language constructs can be used.

see: [provider event types](../types.md#provider-events), [`event details`](../types.md#provider-event-details).

#### Requirement 5.1.2

> When the `provider` signals the occurrence of a particular `event`, the associated `client` and `API` event handlers` **MUST** run.

see: [provider event types](./../types.md#provider-events) and [event handlers](#52-event-handlers).

#### Requirement 5.1.3

> `PROVIDER_ERROR` events **SHOULD** populate the `provider event details`'s `error message` field.

The error message field should contain an informative message as to the nature of the error.

See [event metadata](../types.md#error-event-details)

### 5.2. Event handlers

#### Requirement 5.2.1

> The `client` **MUST** provide an `addHandler` function for associating callbacks with `provider events`, which accepts an `event type` and a `event handler function`.

```java
// run the myClientOnReadyHandler function when the PROVIDER_READY event is fired
client.addHandler(ProviderEvents.Ready, MyClass::myClientOnReadyHandler);
```

see: [provider events](#51-provider-events)

#### Requirement 5.2.2

> The `API` **MUST** provide an `addHandler` function for associating callbacks with `provider events`, which accepts an `event type` and a `event handler function`.

```java
// run the myGlobalErrorHandler function when the PROVIDER_READY event is fired
OpenFeature.addHandler(ProviderEvents.Error, MyClass::myGlobalErrorHandler);
```

see: [provider events](#51-provider-events), [`provider event types`](../types.md#provider-events)

#### Requirement 5.2.3

> The `event details` **MUST** contain the `client name` associated with the event.

The `client name` indicates the client/provider with which the event is associated.
This is particularly relevant for `event handler functions` which are attached to the `API`, not a particular client.

#### Requirement 5.2.4

> The `event handler` function **MUST** accept a `event details` or `error event metadata` parameter.
Kavindu-Dodan marked this conversation as resolved.
Show resolved Hide resolved

see: [`event details`](../types.md#event-details), [`error event metadata`](../types.md#error-event-details)

#### Requirement 5.2.5

> If the provider's `initialize` function terminates normally, `PROVIDER_READY` handlers **MUST** run.
toddbaert marked this conversation as resolved.
Show resolved Hide resolved

See [provider initialization](./02-providers.md#24-initialization) and [setting a provider](./01-flag-evaluation.md#setting-a-provider).

#### Requirement 5.2.6

> If the provider's `initialize` function terminates abnormally, `PROVIDER_ERROR` handlers **MUST** run.

See [provider initialization](./02-providers.md#24-initialization) and [setting a provider](./01-flag-evaluation.md#setting-a-provider).

#### Requirement 5.2.7

> `PROVIDER_READY` handlers added after the provider is already in a ready state **MUST** run immediately.

See [provider initialization](./02-providers.md#24-initialization) and [setting a provider](./01-flag-evaluation.md#setting-a-provider).

Kavindu-Dodan marked this conversation as resolved.
Show resolved Hide resolved
#### Requirement 5.2.8

> If a `handler functions` terminates abnormally, other event handlers **MUST** run.

#### Requirement 5.2.9

> Event handlers **MUST** persist across `provider` changes.

Behavior of event handlers should be independent of the order of handler addition and provider configuration.
46 changes: 46 additions & 0 deletions specification/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,49 @@ An enumeration of possible provider states.
| NOT_READY | The provider has not been initialized. |
| READY | The provider has been initialized, and is able to reliably resolve flag values. |
| ERROR | The provider is initialized but is not able to reliably resolve flag values. |

### Provider Event Details

A structure defining a provider event payload, including:

- flags changed (string[], optional)
- event metadata ([event metadata](#event-metadata))

### Provider Error Event Details

A structure defining a provider error event payload, including:

- error message (string, required)
- event metadata ([flag metadata](#event-metadata))

### Event Details

A structure defining an event payload, including:

- client name (string, required)
- flags changed (string[], optional)
- event metadata ([event metadata](#event-metadata))

### Error Event Details

A structure defining an error event payload, including:

- client name (string, required)
- error message (string, required)
- event metadata ([flag metadata](#event-metadata))
toddbaert marked this conversation as resolved.
Show resolved Hide resolved

### Event Metadata

A structure supporting the addition of arbitrary event data.
It supports definition of arbitrary properties, with keys of type `string`, and values of type `boolean`, `string`, or `number`.

### Provider Events

An enumeration of provider events.
Kavindu-Dodan marked this conversation as resolved.
Show resolved Hide resolved

| Event | Explanation |
| ------------------------------ | --------------------------------------------------------------------------------------------------- |
| PROVIDER_READY | The provider is ready to perform flag evaluations. |
| PROVIDER_ERROR | The provider signalled an error. |
| PROVIDER_CONFIGURATION_CHANGED | A change was made to the backend flag configuration. |
toddbaert marked this conversation as resolved.
Show resolved Hide resolved
| PROVIDER_STALE | The provider's cached state is not longer valid and may not be up-to-date with the source of truth. |