Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/sdk-java-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- name: Compile IWF integration ports
run: ./gradlew compileTestJava --no-daemon
- name: Test credentials and user contracts
run: ./gradlew test --tests io.superdurable.dex.CredentialTest --tests io.superdurable.dex.ApiKeyCredentialTest --tests io.superdurable.dex.FlowServiceTlsTest --tests io.superdurable.dex.contracts.UserContractsTest "-PtestJavaVersion=${{ matrix.java-version }}" --no-daemon
run: ./gradlew test --tests io.superdurable.dex.CredentialTest --tests io.superdurable.dex.ApiKeyCredentialTest --tests io.superdurable.dex.FlowServiceTlsTest --tests io.superdurable.dex.contracts.UserContractsTest --tests io.superdurable.dex.FlowDefinitionConformanceTest "-PtestJavaVersion=${{ matrix.java-version }}" --no-daemon

publication:
name: Maven publication
Expand Down
7 changes: 6 additions & 1 deletion docs/reference/java/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ This page lists user-visible changes to the Java SDK, newest first; each section

## 1.45 {#v1-45}

Not released yet. The next release, sdk-java/v1.45.0, ships these changes.
Not released yet. The next minor release, sdk-java/v1.45.0, ships these changes.

### Added

- **WorkerOptions.Builder.flowDefinitionPaths** and **WorkerOptions.Builder.flowDefinitions** make a **Worker** upload Flow Definition Graph documents when it starts, so Dex Web can draw the Flow types it registers. **FlowDefinitionDocument** holds an in-memory document. Upload failures, including a Server without Flow definition storage, are logged as warnings and never stop the Worker. [Reference](/reference/java/workers#upload-flow-definitions).
- **Client.uploadFlowDefinitions** uploads documents from a deploy or CI script and returns a **FlowDefinitionUploadResult** with a **FlowDefinitionUploadOutcome** for each document. [Reference](/reference/java/client#api-names).

### Fixed

Expand Down
1 change: 1 addition & 0 deletions docs/reference/java/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ them in the [Java SDK API reference](./index.mdx#api-reference).
| Skip a Timer | **skipTimer** | [Skip a Timer](/reference/server/runtime-client#skip-a-timer) |
| Update FlowConfig | **updateFlowConfig** | [Update FlowConfig](./flow.mdx#update-flow-config-with-a-client) |
| Write and read a Stream | **writeStream**, **readStream**, and **listStreamMessages** | [Stream](./stream.mdx) |
| Upload Flow definitions | **uploadFlowDefinitions**, with **FlowDefinitionDocument**; returns **FlowDefinitionUploadResult** values. Since 1.45.0 | [Flow definitions](/reference/server/runtime-client#flow-definitions) |
| Time travel a Flow | **timeTravel**, with **TimeTravelOptions** | [Time travel](/reference/server/runtime-client#time-travel) |
| Handle a failed request | **DexServiceException**, with **ErrorSubStatus** | [Client requests](/reference/server/runtime-client) |

Expand Down
53 changes: 53 additions & 0 deletions docs/reference/java/workers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,59 @@ Call the boolean helper from your probe endpoint and return 200 when true or

Example: [examples/java/src/main/java/io/superdurable/dex/production/pullworkers/PullGreetingExample.java](https://github.com/superdurable/dex/blob/main/examples/java/src/main/java/io/superdurable/dex/production/pullworkers/PullGreetingExample.java)

## Upload Flow definitions {#upload-flow-definitions}

A Worker can upload Flow Definition Graph documents when it starts, so Dex Web
can draw the graph of each Flow type. Since 1.45.0.

| Setting | Java name |
| --- | --- |
| Files and directories of documents | **flowDefinitionPaths** |
| In-memory documents | **flowDefinitions** |

- Each configured path must exist and be readable. An explicitly listed file
must be a Flow Definition Graph 2.x: a strict UTF-8 JSON object whose
**schemaVersion** starts with **2.** and whose **flow.name** is a non-empty
string. The file extension is not checked.
- A directory is read recursively for files whose extension is **.json** in
any case. A file that is not a Flow Definition Graph 2.x, such as
**package.json** or a 1.x document, is skipped with an INFO line.
- A file's Flow type is its **flow.name**. Its generation time is its
top-level **generatedAt**, or the file modification time when it has none.
**generatedAt** must be strict RFC 3339, such as
**2026-11-01T00:00:00Z** or **2026-11-01T02:00:00.5+02:00**. A space
separator, a missing offset, a date alone, or an offset such as **+0200** is
an error, also for a file found in a directory.
- A **FlowDefinitionDocument** carries its Flow type, JSON bytes, and
generation time. Pass a fixed time for a document built from a template.
- Every generation time is truncated to whole milliseconds before upload.
- The **Worker** constructor reads the files. It throws **IllegalArgumentException** for a missing or unreadable path, an invalid explicit file, an invalid **generatedAt**, two sources with the same Flow type, or an in-memory document that is not a Flow Definition Graph 2.x naming its Flow type with a valid **generatedAt**, if any.
- **start** uploads the documents after protocol negotiation and Attribute index synchronization, before it opens task streams. It uploads only the Flow types that the **Registry** registers
and logs the others at INFO. When nothing is left, it sends no request.
- Before upload, an absolute top-level **source.path** becomes relative.
Paths starting with **/**, a drive such as **C:\\**, or **\\\\** count as
absolute on every operating system. Under the working directory, the result
is the remaining segments joined with **/**. Elsewhere, or when the working
directory is unknown, it is the file name. The rewrite needs exactly one
top-level **source** object with exactly one string **path**; otherwise the
original bytes are sent. Only the bytes of that string
change. A relative path is sent unchanged.
- Documents are sent in requests of at most 256 documents and 16 MiB of
content. All requests share one deadline, **attributeIndexSyncTimeout**. Stopping
the Worker cancels an upload in progress.
- The uploader is **sdk-java/** followed by the SDK version.
- Results are logged through **java.util.logging**: CREATED and REPLACED at INFO,
UNCHANGED at FINE, and KEPT_EXISTING at WARNING with both digests and
generation times. An outcome the SDK does not know is logged at WARNING as an
unknown upload outcome.
- Every upload failure is logged at WARNING and the Worker keeps starting.
This includes a Server without Flow definition storage, which returns
UNIMPLEMENTED.

Deploy scripts can call **Client.uploadFlowDefinitions** instead. See
[Flow definitions](/reference/server/runtime-client#flow-definitions) for how
the Server decides between a stored and an uploaded document.

## Capacity and shutdown

| Setting | Java name |
Expand Down
7 changes: 6 additions & 1 deletion docs/reference/rust/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ This page lists user-visible changes to the Rust SDK, newest first; each section

## 1.45 {#v1-45}

Not released yet. The next release, sdk-rust/v1.45.0, ships these changes.
Not released yet. The next minor release, sdk-rust/v1.45.0, ships these changes.

### Added

- **WorkerOptions::flow_definition_paths** and **WorkerOptions::flow_definitions** make a **Worker** upload Flow Definition Graph documents when it starts, so Dex Web can draw the Flow types it registers. **FlowDefinitionDocument** holds an in-memory document. Upload failures, including a Server without Flow definition storage, are logged as warnings and never stop the Worker. [Reference](/reference/rust/workers#upload-flow-definitions).
- **Client::upload_flow_definitions** uploads documents from a deploy or CI script and returns a **FlowDefinitionUploadResult** with a **FlowDefinitionUploadOutcome** for each document. [Reference](/reference/rust/client#api-names).

### Fixed

Expand Down
1 change: 1 addition & 0 deletions docs/reference/rust/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ them in the [Rust SDK API reference](./index.mdx#api-reference).
| Skip a Timer | **skip_timer** | [Skip a Timer](/reference/server/runtime-client#skip-a-timer) |
| Update FlowConfig | **update_flow_config** | [Update FlowConfig](./flow.mdx#update-flow-config-with-a-client) |
| Write and read a Stream | **write_stream**, **read_stream**, and **list_stream_messages** | [Stream](./stream.mdx) |
| Upload Flow definitions | **upload_flow_definitions**, with **FlowDefinitionDocument**; returns **FlowDefinitionUploadResult** values. Since 1.45.0 | [Flow definitions](/reference/server/runtime-client#flow-definitions) |
| Time travel a Flow | **time_travel**, with **TimeTravelOptions** | [Time travel](/reference/server/runtime-client#time-travel) |
| Handle a failed request | **SdkError**, with **ServiceError** and **ErrorSubStatus** | [Client requests](/reference/server/runtime-client) |

Expand Down
53 changes: 53 additions & 0 deletions docs/reference/rust/workers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,59 @@ pub fn is_pull_greeting_ready(worker: &Worker) -> bool {

Example: [examples/rust/src/production/pull_workers.rs](https://github.com/superdurable/dex/blob/main/examples/rust/src/production/pull_workers.rs)

## Upload Flow definitions {#upload-flow-definitions}

A Worker can upload Flow Definition Graph documents when it starts, so Dex Web
can draw the graph of each Flow type. Since 1.45.0.

| Setting | Rust name |
| --- | --- |
| Files and directories of documents | **WorkerOptions::flow_definition_paths** |
| In-memory documents | **WorkerOptions::flow_definitions** |

- Each configured path must exist and be readable. An explicitly listed file
must be a Flow Definition Graph 2.x: a strict UTF-8 JSON object whose
**schemaVersion** starts with **2.** and whose **flow.name** is a non-empty
string. The file extension is not checked.
- A directory is read recursively for files whose extension is **.json** in
any case. A file that is not a Flow Definition Graph 2.x, such as
**package.json** or a 1.x document, is skipped with an info line.
- A file's Flow type is its **flow.name**. Its generation time is its
top-level **generatedAt**, or the file modification time when it has none.
**generatedAt** must be strict RFC 3339, such as
**2026-11-01T00:00:00Z** or **2026-11-01T02:00:00.5+02:00**. A space
separator, a missing offset, a date alone, or an offset such as **+0200** is
an error, also for a file found in a directory.
- A **FlowDefinitionDocument** carries its Flow type, JSON bytes, and
generation time. Pass a fixed time for a document built from a template.
- Every generation time is truncated to whole milliseconds before upload.
- **Worker::try_new** reads the files. It returns **SdkError::FlowDefinition** for a missing or unreadable path, an invalid explicit file, an invalid **generatedAt**, two sources with the same Flow type, or an in-memory document that is not a Flow Definition Graph 2.x naming its Flow type with a valid **generatedAt**, if any.
- **Worker::start** uploads the documents after protocol negotiation and Attribute index synchronization, before it opens task streams. It uploads only the Flow types that the **Registry** registers
and logs the others at info. When nothing is left, it sends no request.
- Before upload, an absolute top-level **source.path** becomes relative.
Paths starting with **/**, a drive such as **C:\\**, or **\\\\** count as
absolute on every operating system. Under the working directory, the result
is the remaining segments joined with **/**. Elsewhere, or when the working
directory is unknown, it is the file name. The rewrite needs exactly one
top-level **source** object with exactly one string **path**; otherwise the
original bytes are sent. Only the bytes of that string
change. A relative path is sent unchanged.
- Documents are sent in requests of at most 256 documents and 16 MiB of
content. All requests share one deadline, **attribute_index_sync_timeout**. Stopping
the Worker cancels an upload in progress.
- The uploader is **sdk-rust/** followed by the SDK version.
- Results are logged through **tracing**: CREATED and REPLACED at info,
UNCHANGED at debug, and KEPT_EXISTING at warn with both digests and
generation times. An outcome the SDK does not know is logged at warn as an
unknown upload outcome.
- Every upload failure is logged at warn and the Worker keeps starting.
This includes a Server without Flow definition storage, which returns
UNIMPLEMENTED.

Deploy scripts can call **Client::upload_flow_definitions** instead. See
[Flow definitions](/reference/server/runtime-client#flow-definitions) for how
the Server decides between a stored and an uploaded document.

## Capacity and shutdown

| Setting | Rust name |
Expand Down
Loading
Loading