-
Notifications
You must be signed in to change notification settings - Fork 10
chore: Add FDv2 data source interfaces. #100
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
Changes from 6 commits
19d9c02
fbea872
adcaa0e
f2b209d
8c115cc
de2fded
98d3b39
da3c639
8fb88ed
da27015
aba46ef
7401331
bba0cdc
89bd017
228f3e6
9469b23
9a450e6
4b8313b
31eb13e
4a2fe3b
3428591
ff60216
e985f80
a956484
ff2376e
194c30c
707fe0e
cb79f5e
b8c5389
a90b536
8d3e869
295138a
ff02c1e
f805c7e
71130ac
bd8e72b
ff95a85
fd6c3af
8243b82
962afb7
fc24f63
e6edc88
1821373
bc10b18
47d55c3
201a92c
117b85c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| package com.launchdarkly.sdk.server.datasources; | ||
| import com.launchdarkly.sdk.internal.fdv2.sources.FDv2ChangeSet; | ||
| import com.launchdarkly.sdk.server.interfaces.DataSourceStatusProvider; | ||
|
|
||
| /** | ||
| * This type is currently experimental and not subject to semantic versioning. | ||
| * <p> | ||
| * The result type for FDv2 initializers and synchronizers. An FDv2 initializer produces a single result, while | ||
| * an FDv2 synchronizer produces a stream of results. | ||
| */ | ||
| public class FDv2SourceResult { | ||
| public enum State { | ||
| /** | ||
| * The data source has encountered an interruption and will attempt to reconnect. | ||
|
kinyoklion marked this conversation as resolved.
Outdated
|
||
| */ | ||
| INTERRUPTED, | ||
| /** | ||
| * The data source has been shut down and will not produce any further results. | ||
| */ | ||
| SHUTDOWN, | ||
| /** | ||
| * The data source has encountered a terminal error and will not produce any further results. | ||
| */ | ||
| TERMINAL_ERROR, | ||
| /** | ||
| * The data source has been instructed to disconnect and will not produce any further results. | ||
| */ | ||
| GOODBYE, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current description of GOODBYE and SHUTDOWN leaves room for me to think GOODBYE -> SHUTDOWN could be a thing. I see the diagrams in the specific ones down below that shows that is not possible, but the enum details make it look like it could be?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GOODBYE is effectively a more specific shutdown. We didn't handle it in .Net because SDKs generally don't seem to have handled it yet, but it also is really hard to handle with data source updates.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically in .Net we had an overload broad SHUTDOWN means I asked the thing to shutdown. |
||
| } | ||
|
|
||
| public enum ResultType { | ||
| /** | ||
| * The source has emitted a change set. This implies that the source is valid. | ||
| */ | ||
| CHANGE_SET, | ||
| /** | ||
| * The source is emitting a status which indicates a transition from being valid to being in some kind | ||
| * of error state. The source will emit a CHANGE_SET if it becomes valid again. | ||
| */ | ||
| STATUS, | ||
| } | ||
|
|
||
| /** | ||
| * Represents a change in the status of the source. | ||
| */ | ||
| public static class Status { | ||
| private final State state; | ||
| private final DataSourceStatusProvider.ErrorInfo errorInfo; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't particularly care for this type, but also we may not want what is effectively a duplicate. |
||
|
|
||
| public State getState() { | ||
| return state; | ||
| } | ||
|
|
||
| public DataSourceStatusProvider.ErrorInfo getErrorInfo() { | ||
| return errorInfo; | ||
| } | ||
|
|
||
| public Status(State state, DataSourceStatusProvider.ErrorInfo errorInfo) { | ||
| this.state = state; | ||
| this.errorInfo = errorInfo; | ||
| } | ||
| } | ||
| private final FDv2ChangeSet changeSet; | ||
| private final Status status; | ||
|
|
||
| private final ResultType resultType; | ||
|
|
||
| private FDv2SourceResult(FDv2ChangeSet changeSet, Status status, ResultType resultType) { | ||
| this.changeSet = changeSet; | ||
| this.status = status; | ||
| this.resultType = resultType; | ||
| } | ||
|
|
||
| public static FDv2SourceResult interrupted(DataSourceStatusProvider.ErrorInfo errorInfo) { | ||
| return new FDv2SourceResult(null, new Status(State.INTERRUPTED, errorInfo), ResultType.STATUS); | ||
| } | ||
|
|
||
| public static FDv2SourceResult shutdown(DataSourceStatusProvider.ErrorInfo errorInfo) { | ||
| return new FDv2SourceResult(null, new Status(State.SHUTDOWN, errorInfo), ResultType.STATUS); | ||
| } | ||
|
|
||
| public static FDv2SourceResult changeSet(FDv2ChangeSet changeSet) { | ||
| return new FDv2SourceResult(changeSet, null, ResultType.CHANGE_SET); | ||
| } | ||
|
|
||
| public ResultType getResultType() { | ||
| return resultType; | ||
| } | ||
|
|
||
| public Status getStatus() { | ||
| return status; | ||
| } | ||
|
|
||
| public FDv2ChangeSet getChangeSet() { | ||
| return changeSet; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package com.launchdarkly.sdk.server.datasources; | ||
|
|
||
| import java.util.concurrent.CompletableFuture; | ||
|
|
||
| /** | ||
| * This type is currently experimental and not subject to semantic versioning. | ||
| * <p> | ||
| * Interface for an asynchronous data source initializer. | ||
| * <p> | ||
| * An initializer will run and produce a single result. If the initializer is successful, then it should emit a result | ||
| * containing a change set. If the initializer fails, then it should emit a status result describing the error. | ||
| * <p> | ||
| * [START] | ||
| * │ | ||
| * ▼ | ||
| * ┌─────────────┐ | ||
| * │ RUNNING │──┐ | ||
| * └─────────────┘ │ | ||
| * │ │ │ │ │ | ||
| * │ │ │ │ └──► SHUTDOWN ───► [END] | ||
| * │ │ │ │ | ||
| * │ │ │ └─────► INTERRUPTED ───► [END] | ||
| * │ │ │ | ||
| * │ │ └─────────► CHANGESET ───► [END] | ||
| * │ │ | ||
| * │ └─────────────► TERMINAL_ERROR ───► [END] | ||
| * │ | ||
| * └─────────────────► GOODBYE ───► [END] | ||
| * | ||
| * <code> | ||
| * stateDiagram-v2 | ||
| * [*] --> RUNNING | ||
| * RUNNING --> SHUTDOWN | ||
| * RUNNING --> INTERRUPTED | ||
| * RUNNING --> CHANGESET | ||
| * RUNNING --> TERMINAL_ERROR | ||
| * RUNNING --> GOODBYE | ||
| * SHUTDOWN --> [*] | ||
| * INTERRUPTED --> [*] | ||
| * CHANGESET --> [*] | ||
| * TERMINAL_ERROR --> [*] | ||
| * GOODBYE --> [*] | ||
| * </code> | ||
| */ | ||
| public interface Initializer { | ||
| /** | ||
| * Run the initializer to completion. | ||
| * @return The result of the initializer. | ||
| */ | ||
| CompletableFuture<FDv2SourceResult> run(); | ||
|
|
||
| /** | ||
| * Shutdown the initializer. The initializer should emit a status event with a SHUTDOWN state as soon as possible. | ||
| * If the initializer has already completed, or is in the process of completing, this method should have no effect. | ||
| */ | ||
| void shutdown(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| package com.launchdarkly.sdk.server.datasources; | ||
|
|
||
| import java.util.concurrent.CompletableFuture; | ||
|
|
||
| /** | ||
| * This type is currently experimental and not subject to semantic versioning. | ||
| * <p> | ||
| * Interface for an asynchronous data source synchronizer. | ||
| * <p> | ||
| * A synchronizer will run and produce a stream of results. When it experiences a temporary failure, it will emit a | ||
| * status event indicating that it is INTERRUPTED, while it attempts to resolve its failure. When it receives data, | ||
| * it should emit a result containing a change set. When the data source is shut down gracefully, it should emit a | ||
| * status event indicating that it is SHUTDOWN. | ||
| * <p> | ||
| * [START] | ||
| * │ | ||
| * ▼ | ||
| * ┌─────────────┐ | ||
| * ┌─►│ RUNNING │──┐ | ||
| * │ └─────────────┘ │ | ||
| * │ │ │ │ │ │ | ||
| * │ │ │ │ │ └──► SHUTDOWN ───► [END] | ||
| * │ │ │ │ │ | ||
| * │ │ │ │ └──────► TERMINAL_ERROR ───► [END] | ||
| * │ │ │ │ | ||
| * │ │ │ └──────────► GOODBYE ───► [END] | ||
| * │ │ │ | ||
| * │ │ └──────────────► CHANGE_SET ───┐ | ||
| * │ │ │ | ||
| * │ └──────────────────► INTERRUPTED ──┤ | ||
| * │ │ | ||
| * └──────────────────────────────────────┘ | ||
| * <p> | ||
| * <code> | ||
| * stateDiagram-v2 | ||
| * [*] --> RUNNING | ||
| * RUNNING --> SHUTDOWN | ||
| * SHUTDOWN --> [*] | ||
| * RUNNING --> TERMINAL_ERROR | ||
| * TERMINAL_ERROR --> [*] | ||
| * RUNNING --> GOODBYE | ||
| * GOODBYE --> [*] | ||
| * RUNNING --> CHANGE_SET | ||
| * CHANGE_SET --> RUNNING | ||
| * RUNNING --> INTERRUPTED | ||
| * INTERRUPTED --> RUNNING | ||
| * </code> | ||
| */ | ||
| interface Synchronizer { | ||
| /** | ||
| * Get the next result from the stream. | ||
| * @return a future that will complete when the next result is available | ||
| */ | ||
| CompletableFuture<FDv2SourceResult> next(); | ||
|
|
||
| /** | ||
| * Shutdown the synchronizer. The synchronizer should emit a status event with a SHUTDOWN state as soon as possible | ||
| * and then stop producing further results. If the synchronizer involves a resource, such as a network connection, | ||
| * then those resources should be released. | ||
| * If the synchronizer has already completed, or is in the process of completing, this method should have no effect. | ||
| */ | ||
| void shutdown(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want running in this enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I shouldn't call it
State. Its more like a notification of change, and it doesn't representsvalid/runningbecause that is handled by a changeset.