diff --git a/docs/develop/rust/_category_.json b/docs/develop/rust/_category_.json new file mode 100644 index 00000000..9a07f403 --- /dev/null +++ b/docs/develop/rust/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Rust SDK", + "position": 5, + "link": { + "type": "generated-index" + } +} diff --git a/docs/develop/rust/overview.mdx b/docs/develop/rust/overview.mdx new file mode 100644 index 00000000..95af3a71 --- /dev/null +++ b/docs/develop/rust/overview.mdx @@ -0,0 +1,14 @@ +--- +sidebar_position: 1 +description: "Get an idea of what a Restate Rust service looks like." +--- + +import Admonition from '@theme/Admonition'; + +# Overview + +The Restate Rust SDK is open source and can be found on GitHub: ([sdk-rust repo](https://github.com/restatedev/sdk-rust)). + + +The Rust SDK documentation is still under construction. Please refer to the [Rust hello-world template](https://github.com/restatedev/examples/tree/main/templates/rust) and the [`restate-sdk` crate docs](https://docs.rs/restate-sdk/latest/restate_sdk/) to get started. + diff --git a/docs/references/errors.md b/docs/references/errors.md index 42cad68e..6e4dd7d5 100644 --- a/docs/references/errors.md +++ b/docs/references/errors.md @@ -62,7 +62,7 @@ Suggestions: * Up/Downgrade your Restate server to the requested version. * Migrate your data to the requested version by running the migration scripts. -* Wipe your meta storage directory to start afresh via `--wipe=meta`. +* Wipe your meta storage directory to start afresh via `rm -rf //local-metadata-store`. * Configure a different meta storage directory via `meta.storage_path`.

META0011

@@ -71,7 +71,7 @@ Non-empty meta storage directory, configured via `meta.storage_path`, is missing Suggestions: -* Wipe your meta storage directory to start afresh via `--wipe=meta`. +* Wipe your meta storage directory to start afresh via `rm -rf //local-metadata-store`. * Configure a different meta storage directory via `meta.storage_path`. * Downgrade your Restate server to {'<='} 0.7. @@ -95,6 +95,26 @@ Suggestions: * Either deploy a server version which is compatible with your SDK * Or use an SDK version which is compatible with your server +

META0014

+ +Service discovery response failed, and the server may have responded in HTTP1.1. +This can happen when discovering locally running dev servers from Faas platforms +eg `wrangler dev`. FaaS platforms in generally will support HTTP2, however, so +this is only a local development concern. + +You can try to discover the endpoint with `--use-http1.1` when working +with these local dev servers. This should not be needed in production. + +

META0015

+ +The service discovery response suggested that the SDK is serving in +bidirectional protocol mode, but discovery is going over a protocol that does +not support it (currently only Lambda). + +Lambda endpoints do not support the bidirectional protocol mode and should be +configured to announce themselves as being in request-response mode upon +discovery. +

RT0001

The invocation response stream was aborted due to the timeout configured in `worker.invoker.abort_timeout`. @@ -159,7 +179,7 @@ Trying to open worker storage directory, configured via `worker.storage_rocksdb. Suggestions: -* Wipe your worker storage directory to start afresh via `--wipe=worker`. +* Wipe your meta storage directory to start afresh via `rm -rf //db`. * Configure a different worker storage directory via `worker.storage_rocksdb.path`. * Downgrade your Restate server to < 0.8. diff --git a/docs/references/sql-introspection.md b/docs/references/sql-introspection.md index 6a2dc5db..3f4de438 100644 --- a/docs/references/sql-introspection.md +++ b/docs/references/sql-introspection.md @@ -31,6 +31,7 @@ To learn how to access the instrospection interface, check out the [instrospecti | `invoked_id` | `Utf8` | If this entry represents an outbound invocation, indicates the ID of that invocation. | | `invoked_target` | `Utf8` | If this entry represents an outbound invocation, indicates the invocation Target. Format for plain services: `ServiceName/HandlerName`, e.g. `Greeter/greet`. Format for virtual objects/workflows: `VirtualObjectName/Key/HandlerName`, e.g. `Greeter/Francesco/greet`. | | `sleep_wakeup_at` | `Date64` | If this entry represents a sleep, indicates wakeup time. | +| `promise_name` | `Utf8` | If this entry is a promise related entry (GetPromise, PeekPromise, CompletePromise), indicates the promise name. | | `raw` | `Binary` | Raw binary representation of the entry. Check the [service protocol](https://github.com/restatedev/service-protocol) for more details to decode it. | ## Table: `sys_keyed_service_status` @@ -115,6 +116,10 @@ To learn how to access the instrospection interface, check out the [instrospecti | `journal_size` | `UInt32` | The number of journal entries durably logged for this invocation. | | `created_at` | `Date64` | Timestamp indicating the start of this invocation. | | `modified_at` | `Date64` | Timestamp indicating the last invocation status transition. For example, last time the status changed from `invoked` to `suspended`. | +| `inboxed_at` | `Date64` | Timestamp indicating when the invocation was inboxed, if ever. | +| `scheduled_at` | `Date64` | Timestamp indicating when the invocation was scheduled, if ever. | +| `running_at` | `Date64` | Timestamp indicating when the invocation first transitioned to running, if ever. | +| `completed_at` | `Date64` | Timestamp indicating when the invocation was completed, if ever. | | `retry_count` | `UInt64` | The number of invocation attempts since the current leader started executing it. Increments on start, so a value greater than 1 means a failure occurred. Note: the value is not a global attempt counter across invocation suspensions and leadership changes. | | `last_start_at` | `Date64` | Timestamp indicating the start of the most recent attempt of this invocation. | | `next_retry_at` | `Date64` | Timestamp indicating the start of the next attempt of this invocation. | @@ -125,5 +130,7 @@ To learn how to access the instrospection interface, check out the [instrospecti | `last_failure_related_entry_index` | `UInt64` | The index of the journal entry that caused the failure, if any. It may be out-of-bound of the currently stored entries in `sys_journal`. | | `last_failure_related_entry_name` | `Utf8` | The name of the journal entry that caused the failure, if any. | | `last_failure_related_entry_type` | `Utf8` | The type of the journal entry that caused the failure, if any. You can check all the available entry types in [`entries.rs`](https://github.com/restatedev/restate/blob/main/crates/types/src/journal/entries.rs). | -| `status` | `Utf8` | Either `pending` or `ready` or `running` or `backing-off` or `suspended` or `completed`. | +| `status` | `Utf8` | Either `pending` or `scheduled` or `ready` or `running` or `backing-off` or `suspended` or `completed`. | +| `completion_result` | `Utf8` | If `status = 'completed'`, this contains either `success` or `failure` | +| `completion_failure` | `Utf8` | If `status = 'completed' AND completion_result = 'failure'`, this contains the error cause | diff --git a/restate.config.json b/restate.config.json index bee39696..584e9978 100644 --- a/restate.config.json +++ b/restate.config.json @@ -1,7 +1,7 @@ { - "RESTATE_VERSION": "1.0", + "RESTATE_VERSION": "1.1", "TYPESCRIPT_SDK_VERSION": "1.3.0", "JAVA_SDK_VERSION": "1.0.1", - "GO_SDK_VERSION": "0.10.0", - "PYTHON_SDK_VERSION": "0.2.0" + "GO_SDK_VERSION": "0.11.0", + "PYTHON_SDK_VERSION": "0.3.0" } \ No newline at end of file diff --git a/static/schemas/config_schema.json b/static/schemas/config_schema.json index e63be695..6475e85b 100644 --- a/static/schemas/config_schema.json +++ b/static/schemas/config_schema.json @@ -3,13 +3,20 @@ "title": "Restate configuration file", "description": "Configuration for Restate server.", "type": "object", + "required": [ + "tracing-filter", + "tracing-headers" + ], "properties": { "worker": { "default": { - "internal-queue-length": 10000, + "cleanup-interval": "1h", + "experimental-feature-new-invocation-status-table": false, + "internal-queue-length": 1000, "invoker": { "abort-timeout": "1m", - "concurrent-invocations-limit": 10000, + "concurrent-invocations-limit": 100, + "in-memory-queue-length-limit": 1056784, "inactivity-timeout": "1m", "message-size-limit": null, "message-size-warning": "10.0 MB", @@ -22,6 +29,7 @@ }, "tmp-dir": null }, + "max-command-batch-size": 4, "num-timers-in-memory-limit": null, "storage": { "persist-lsn-interval": "1h", @@ -36,6 +44,7 @@ "default": { "bind-address": "0.0.0.0:9070", "concurrent-api-requests-limit": null, + "default-replication-strategy": "on-all-nodes", "heartbeat-interval": "1s 500ms", "log-trim-interval": "1h", "log-trim-threshold": 1000, @@ -58,14 +67,25 @@ }, "bifrost": { "default": { + "append-retry-max-interval": "1s", + "append-retry-min-interval": "10ms", "default-provider": "local", + "default-provider-config": null, "local": { "rocksdb-disable-wal": false, "rocksdb-disable-wal-fsync": false, "rocksdb-memory-ratio": 0.5, "writer-batch-commit-count": 5000, "writer-batch-commit-duration": "0s" - } + }, + "read-retry-policy": { + "factor": 2.0, + "initial-interval": "50ms", + "max-attempts": 50, + "max-interval": "1s", + "type": "exponential" + }, + "seal-retry-interval": "2s" }, "$ref": "#/definitions/BifrostOptions" }, @@ -80,6 +100,29 @@ }, "$ref": "#/definitions/LocalMetadataStoreOptions" }, + "networking": { + "default": { + "connect-retry-policy": { + "factor": 2.0, + "initial-interval": "10ms", + "max-attempts": 10, + "max-interval": "500ms", + "type": "exponential" + }, + "handshake-timeout": "3s" + }, + "$ref": "#/definitions/NetworkingOptions" + }, + "log-server": { + "default": { + "incoming-network-queue-length": 1000, + "rocksdb-disable-wal": false, + "rocksdb-disable-wal-fsync": false, + "rocksdb-memory-ratio": 0.5, + "writer-batch-commit-count": 5000 + }, + "$ref": "#/definitions/LogServer" + }, "roles": { "description": "Defines the roles which this Restate node should run, by default the node starts with all roles.", "default": [ @@ -128,11 +171,6 @@ "null" ] }, - "metadata-store-address": { - "description": "Address of the metadata store server to bootstrap the node from.", - "default": "http://127.0.0.1:5123/", - "type": "string" - }, "bind-address": { "description": "Address to bind for the Node server. Default is `0.0.0.0:5122`", "default": "0.0.0.0:5122", @@ -145,10 +183,10 @@ }, "bootstrap-num-partitions": { "title": "Partitions", - "description": "Number of partitions that will be provisioned during cluster bootstrap, partitions used to process messages.\n\nNOTE: This config entry only impacts the initial number of partitions, the value of this entry is ignored for bootstrapped nodes/clusters.\n\nCannot be higher than `4611686018427387903` (You should almost never need as many partitions anyway)", + "description": "Number of partitions that will be provisioned during cluster bootstrap, partitions used to process messages.\n\nNOTE: This config entry only impacts the initial number of partitions, the value of this entry is ignored for bootstrapped nodes/clusters.\n\nCannot be higher than `65535` (You should almost never need as many partitions anyway)", "default": 24, "type": "integer", - "format": "uint64", + "format": "uint16", "minimum": 1.0 }, "shutdown-timeout": { @@ -167,28 +205,6 @@ "format": "uint", "minimum": 0.0 }, - "tracing-endpoint": { - "title": "Tracing Endpoint", - "description": "Specify the tracing endpoint to send traces to. Traces will be exported using [OTLP gRPC](https://opentelemetry.io/docs/specs/otlp/#otlpgrpc) through [opentelemetry_otlp](https://docs.rs/opentelemetry-otlp/0.12.0/opentelemetry_otlp/).\n\nTo configure the sampling, please refer to the [opentelemetry autoconfigure docs](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#sampler).", - "type": [ - "string", - "null" - ] - }, - "tracing-json-path": { - "title": "Distributed Tracing JSON Export Path", - "description": "If set, an exporter will be configured to write traces to files using the Jaeger JSON format. Each trace file will start with the `trace` prefix.\n\nIf unset, no traces will be written to file.\n\nIt can be used to export traces in a structured format without configuring a Jaeger agent.\n\nTo inspect the traces, open the Jaeger UI and use the Upload JSON feature to load and inspect them.", - "type": [ - "string", - "null" - ] - }, - "tracing-filter": { - "title": "Tracing Filter", - "description": "Distributed tracing exporter filter. Check the [`RUST_LOG` documentation](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html) for more details how to configure it.", - "default": "info", - "type": "string" - }, "log-filter": { "title": "Logging Filter", "description": "Log filter configuration. Can be overridden by the `RUST_LOG` environment variable. Check the [`RUST_LOG` documentation](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html) for more details how to configure it.", @@ -286,6 +302,73 @@ "default": "enable-count", "$ref": "#/definitions/RocksbPerfStatisticsLevel" }, + "metadata-update-interval": { + "title": "Metadata update interval", + "description": "The interval at which each node checks for metadata updates it has observed from different nodes or other sources.", + "default": "3s", + "type": "string" + }, + "network-error-retry-policy": { + "title": "Network error retry policy", + "description": "The retry policy for node network error", + "default": { + "factor": 2.0, + "initial-interval": "10ms", + "max-attempts": 15, + "max-interval": "5s", + "type": "exponential" + }, + "$ref": "#/definitions/RetryPolicy" + }, + "metadata-store-client": { + "description": "Metadata store server to bootstrap the node from.", + "default": { + "address": "http://127.0.0.1:5123/", + "type": "embedded" + }, + "$ref": "#/definitions/MetadataStoreClient" + }, + "metadata-store-client-backoff-policy": { + "title": "Backoff policy used by the metadata store client", + "description": "Backoff policy used by the metadata store client when it encounters concurrent modifications.", + "default": { + "factor": 2.0, + "initial-interval": "10ms", + "max-attempts": null, + "max-interval": "100ms", + "type": "exponential" + }, + "$ref": "#/definitions/RetryPolicy" + }, + "tracing-endpoint": { + "title": "Tracing Endpoint", + "description": "Specify the tracing endpoint to send traces to. Traces will be exported using [OTLP gRPC](https://opentelemetry.io/docs/specs/otlp/#otlpgrpc) through [opentelemetry_otlp](https://docs.rs/opentelemetry-otlp/0.12.0/opentelemetry_otlp/).\n\nTo configure the sampling, please refer to the [opentelemetry autoconfigure docs](https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#sampler).", + "type": [ + "string", + "null" + ] + }, + "tracing-json-path": { + "title": "Distributed Tracing JSON Export Path", + "description": "If set, an exporter will be configured to write traces to files using the Jaeger JSON format. Each trace file will start with the `trace` prefix.\n\nIf unset, no traces will be written to file.\n\nIt can be used to export traces in a structured format without configuring a Jaeger agent.\n\nTo inspect the traces, open the Jaeger UI and use the Upload JSON feature to load and inspect them.", + "type": [ + "string", + "null" + ] + }, + "tracing-filter": { + "title": "Tracing Filter", + "description": "Distributed tracing exporter filter. Check the [`RUST_LOG` documentation](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html) for more details how to configure it.", + "type": "string" + }, + "tracing-headers": { + "title": "Additional tracing headers", + "description": "Specify additional headers you want the system to send to the tracing endpoint (e.g. authentication headers).", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "request-identity-private-key-pem-file": { "title": "Request identity private key PEM file", "description": "A path to a file, such as \"/var/secrets/key.pem\", which contains exactly one ed25519 private key in PEM format. Such a file can be generated with `openssl genpkey -algorithm ed25519`. If provided, this key will be used to attach JWTs to requests from this client which SDKs may optionally verify, proving that the caller is a particular Restate instance.\n\nThis file is currently only read on client creation, but this may change in future. Parsed public keys will be logged at INFO level in the same format that SDKs expect.", @@ -406,7 +489,7 @@ "properties": { "internal-queue-length": { "title": "Internal queue for partition processor communication", - "default": 10000, + "default": 1000, "type": "integer", "format": "uint", "minimum": 1.0 @@ -421,6 +504,12 @@ "format": "uint", "minimum": 1.0 }, + "cleanup-interval": { + "title": "Cleanup interval", + "description": "In order to clean up completed invocations, that is invocations invoked with an idempotency id, or workflows, Restate periodically scans among the completed invocations to check whether they need to be removed or not. This interval sets the scan interval of the cleanup procedure. Default: 1 hour.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format.", + "default": "1h", + "type": "string" + }, "storage": { "default": { "persist-lsn-interval": "1h", @@ -433,7 +522,8 @@ "invoker": { "default": { "abort-timeout": "1m", - "concurrent-invocations-limit": 10000, + "concurrent-invocations-limit": 100, + "in-memory-queue-length-limit": 1056784, "inactivity-timeout": "1m", "message-size-limit": null, "message-size-warning": "10.0 MB", @@ -447,6 +537,14 @@ "tmp-dir": null }, "$ref": "#/definitions/InvokerOptions" + }, + "max-command-batch-size": { + "title": "Maximum command batch size for partition processors", + "description": "The maximum number of commands a partition processor will apply in a batch. The larger this value is, the higher the throughput and latency are.", + "default": 4, + "type": "integer", + "format": "uint", + "minimum": 1.0 } } }, @@ -460,7 +558,7 @@ "integer", "null" ], - "format": "uint64", + "format": "uint16", "minimum": 1.0 }, "rocksdb-memory-budget": { @@ -673,10 +771,18 @@ "null" ] }, + "in-memory-queue-length-limit": { + "title": "Spill invocations to disk", + "description": "Defines the threshold after which queues invocations will spill to disk at the path defined in `tmp-dir`. In other words, this is the number of invocations that can be kept in memory before spilling to disk.", + "default": 1056784, + "type": "integer", + "format": "uint", + "minimum": 1.0 + }, "concurrent-invocations-limit": { "title": "Limit number of concurrent invocations from this node", "description": "Number of concurrent invocations that can be processed by the invoker.", - "default": 10000, + "default": 100, "type": [ "integer", "null" @@ -692,7 +798,7 @@ "oneOf": [ { "title": "None", - "description": "No retries strategy.", + "description": "No retry strategy.", "type": "object", "required": [ "type" @@ -838,6 +944,12 @@ "type": "integer", "format": "uint64", "minimum": 0.0 + }, + "default-replication-strategy": { + "title": "Default replication strategy", + "description": "The default replication strategy to be used by the cluster controller to schedule partition processors.", + "default": "on-all-nodes", + "$ref": "#/definitions/ReplicationStrategy" } } }, @@ -877,6 +989,33 @@ } } }, + "ReplicationStrategy": { + "description": "Replication strategy for partition processors.", + "oneOf": [ + { + "description": "Schedule partition processor replicas on all available nodes", + "type": "string", + "enum": [ + "on-all-nodes" + ] + }, + { + "description": "Schedule this number of partition processor replicas", + "type": "object", + "required": [ + "factor" + ], + "properties": { + "factor": { + "type": "integer", + "format": "uint32", + "minimum": 1.0 + } + }, + "additionalProperties": false + } + ] + }, "IngressOptions": { "title": "Ingress options", "type": "object", @@ -938,6 +1077,13 @@ "default": "local", "$ref": "#/definitions/ProviderKind" }, + "default-provider-config": { + "description": "An opaque string that gets passed to the loglet provider to seed the creation of new loglets.", + "type": [ + "string", + "null" + ] + }, "local": { "description": "Configuration of local loglet provider", "default": { @@ -948,6 +1094,36 @@ "writer-batch-commit-duration": "0s" }, "type": "string" + }, + "read-retry-policy": { + "title": "Read retry policy", + "description": "Retry policy to use when bifrost waits for reconfiguration to complete during read operations", + "default": { + "factor": 2.0, + "initial-interval": "50ms", + "max-attempts": 50, + "max-interval": "1s", + "type": "exponential" + }, + "$ref": "#/definitions/RetryPolicy" + }, + "seal-retry-interval": { + "title": "Seal retry interval", + "description": "Interval to wait between retries of loglet seal failures", + "default": "2s", + "type": "string" + }, + "append-retry-min-interval": { + "title": "Append retry minimum interval", + "description": "Minimum retry duration used by the exponential backoff mechanism for bifrost appends.", + "default": "10ms", + "type": "string" + }, + "append-retry-max-interval": { + "title": "Append retry maximum interval", + "description": "Maximum retry duration used by the exponential backoff mechanism for bifrost appends.", + "default": "1s", + "type": "string" } } }, @@ -1085,26 +1261,166 @@ } } }, + "NetworkingOptions": { + "title": "Networking options", + "type": "object", + "properties": { + "connect-retry-policy": { + "title": "Retry policy", + "description": "Retry policy to use for internal node-to-node networking.", + "default": { + "factor": 2.0, + "initial-interval": "10ms", + "max-attempts": 10, + "max-interval": "500ms", + "type": "exponential" + }, + "$ref": "#/definitions/RetryPolicy" + }, + "handshake-timeout": { + "title": "Handshake timeout", + "description": "Timeout for handshake message for internal node-to-node networking.", + "default": "3s", + "type": "string" + } + } + }, + "LogServer": { + "title": "Log server options", + "description": "Configuration is only used on nodes running with `log-server` role.", + "type": "object", + "properties": { + "rocksdb-memory-budget": { + "description": "The memory budget for rocksdb memtables in bytes\n\nIf this value is set, it overrides the ratio defined in `rocksdb-memory-ratio`.", + "anyOf": [ + { + "$ref": "#/definitions/NonZeroHumanBytes" + }, + { + "type": "null" + } + ] + }, + "rocksdb-memory-ratio": { + "description": "The memory budget for rocksdb memtables as ratio\n\nThis defines the total memory for rocksdb as a ratio of all memory available to the log-server.\n\n(See `rocksdb-total-memtables-ratio` in common).", + "default": 0.5, + "type": "number", + "format": "float" + }, + "rocksdb-disable-wal-fsync": { + "description": "Disable fsync of WAL on every batch", + "default": false, + "type": "boolean" + }, + "writer-batch-commit-count": { + "description": "Trigger a commit when the batch size exceeds this threshold.\n\nSet to 0 or 1 to commit the write batch on every command.", + "default": 5000, + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "incoming-network-queue-length": { + "description": "The number of messages that can queue up on input network stream while request processor is busy.", + "default": 1000, + "type": "integer", + "format": "uint", + "minimum": 1.0 + }, + "rocksdb-disable-direct-io-for-reads": { + "title": "Disable Direct IO for reads", + "description": "Files will be opened in \"direct I/O\" mode which means that data r/w from the disk will not be cached or buffered. The hardware buffer of the devices may however still be used. Memory mapped files are not impacted by these parameters.", + "type": [ + "boolean", + "null" + ] + }, + "rocksdb-disable-direct-io-for-flush-and-compactions": { + "title": "Disable Direct IO for flush and compactions", + "description": "Use O_DIRECT for writes in background flush and compactions.", + "type": [ + "boolean", + "null" + ] + }, + "rocksdb-disable-wal": { + "title": "Disable WAL", + "description": "The default depends on the different rocksdb use-cases at Restate.\n\nSupports hot-reloading (Partial / Bifrost only)", + "type": [ + "boolean", + "null" + ] + }, + "rocksdb-disable-statistics": { + "description": "Disable rocksdb statistics collection\n\nDefault: False (statistics enabled)", + "type": [ + "boolean", + "null" + ] + }, + "rocksdb-max-background-jobs": { + "title": "RocksDB max background jobs (flushes and compactions)", + "description": "Default: the number of CPU cores on this node.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 1.0 + }, + "rocksdb-compaction-readahead-size": { + "title": "RocksDB compaction readahead size in bytes", + "description": "If non-zero, we perform bigger reads when doing compaction. If you're running RocksDB on spinning disks, you should set this to at least 2MB. That way RocksDB's compaction is doing sequential instead of random reads.", + "anyOf": [ + { + "$ref": "#/definitions/NonZeroHumanBytes" + }, + { + "type": "null" + } + ] + }, + "rocksdb-statistics-level": { + "title": "RocksDB statistics level", + "description": "StatsLevel can be used to reduce statistics overhead by skipping certain types of stats in the stats collection process.\n\nDefault: \"except-detailed-timers\"", + "anyOf": [ + { + "$ref": "#/definitions/RocksbStatistics" + }, + { + "type": "null" + } + ] + } + } + }, "Role": { "oneOf": [ { + "description": "A worker runs partition processor (journal, state, and drives invocations)", "type": "string", "enum": [ - "metadata-store" + "worker" ] }, { - "description": "A worker runs partition processor (journal, state, and drives invocations)", + "description": "Admin runs cluster controller and user-facing admin APIs", "type": "string", "enum": [ - "worker" + "admin" ] }, { - "description": "Admin runs cluster controller and user-facing admin APIs", + "description": "Serves the metadata store", "type": "string", "enum": [ - "admin" + "metadata-store" + ] + }, + { + "description": "[IN DEVELOPMENT] Serves a log server for replicated loglets", + "type": "string", + "enum": [ + "log-server" ] } ] @@ -1177,6 +1493,50 @@ } ] }, + "MetadataStoreClient": { + "title": "Metadata Store", + "description": "Definition of a bootstrap metadata store", + "oneOf": [ + { + "description": "Connects to an embedded metadata store that is run by nodes that run with the MetadataStore role.", + "type": "object", + "required": [ + "address", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "embedded" + ] + }, + "address": { + "type": "string" + } + } + }, + { + "description": "Uses external etcd as metadata store. The addresses are formatted as `host:port`", + "type": "object", + "required": [ + "addresses", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "etcd" + ] + }, + "addresses": { + "type": "string" + } + } + } + ] + }, "Http2KeepAliveOptions": { "title": "HTTP/2 Keep alive options", "description": "Configuration for the HTTP/2 keep-alive mechanism, using PING frames.\n\nPlease note: most gateways don't propagate the HTTP/2 keep-alive between downstream and upstream hosts. In those environments, you need to make sure the gateway can detect a broken connection to the upstream deployment(s).", diff --git a/static/schemas/openapi-admin.json b/static/schemas/openapi-admin.json index 75d00ca4..52e62154 100644 --- a/static/schemas/openapi-admin.json +++ b/static/schemas/openapi-admin.json @@ -1 +1 @@ -{"openapi":"3.0.0","info":{"title":"Admin API","version":"1.0.0"},"paths":{"/deployments":{"get":{"tags":["deployment"],"summary":"List deployments","description":"List all registered deployments.","operationId":"list_deployments","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDeploymentsResponse"}}}}}},"post":{"tags":["deployment"],"summary":"Create deployment","description":"Create deployment. Restate will invoke the endpoint to gather additional information required for registration, such as the services exposed by the deployment. If the deployment is already registered, this method will fail unless `force` is set to `true`.","operationId":"create_deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions/{subscription}":{"get":{"tags":["subscription"],"summary":"Get subscription","description":"Get subscription","operationId":"get_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["subscription"],"summary":"Delete subscription","description":"Delete subscription.","operationId":"delete_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services":{"get":{"tags":["service"],"summary":"List services","description":"List all registered services.","operationId":"list_services","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServicesResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers/{handler}":{"get":{"tags":["service_handler"],"summary":"Get service handler","description":"Get the handler of a service","operationId":"get_service_handler","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}},{"name":"handler","in":"path","description":"Handler name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers":{"get":{"tags":["service_handler"],"summary":"List service handlers","description":"List all the handlers of the given service.","operationId":"list_service_handlers","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServiceHandlersResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments/{deployment}":{"get":{"tags":["deployment"],"summary":"Get deployment","description":"Get deployment metadata","operationId":"get_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["deployment"],"summary":"Delete deployment","description":"Delete deployment. Currently it's supported to remove a deployment only using the force flag","operationId":"delete_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","description":"If true, the deployment will be forcefully deleted. This might break in-flight invocations, use with caution.","style":"simple","schema":{"type":"boolean"}}],"responses":{"202":{"description":"Accepted"},"501":{"description":"Not implemented. Only using the force flag is supported at the moment."},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions":{"get":{"tags":["subscription"],"summary":"List subscriptions","description":"List all subscriptions.","operationId":"list_subscriptions","parameters":[{"name":"sink","in":"query","description":"Filter by the exact specified sink.","style":"simple","schema":{"type":"string"}},{"name":"source","in":"query","description":"Filter by the exact specified source.","style":"simple","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSubscriptionsResponse"}}}}}},"post":{"tags":["subscription"],"summary":"Create subscription","description":"Create subscription.","operationId":"create_subscription","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/health":{"get":{"tags":["health"],"summary":"Health check","description":"Check REST API Health.","operationId":"health","responses":{"200":{"description":"OK"}}}},"/services/{service}":{"get":{"tags":["service"],"summary":"Get service","description":"Get a registered service.","operationId":"get_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"patch":{"tags":["service"],"summary":"Modify a service","description":"Modify a registered service.","operationId":"modify_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/openapi":{"get":{"tags":["openapi"],"summary":"OpenAPI specification","externalDocs":{"url":"https://swagger.io/specification/"},"operationId":"openapi_spec","responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}}}},"/version":{"get":{"tags":["version"],"summary":"Admin version information","description":"Obtain admin version information.","operationId":"version","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInformation"}}}}}}},"/invocations/{invocation_id}":{"delete":{"tags":["invocation"],"summary":"Delete an invocation","description":"Delete the given invocation. By default, an invocation is terminated by gracefully cancelling it. This ensures virtual object state consistency. Alternatively, an invocation can be killed which does not guarantee consistency for virtual object instance state, in-flight invocations to other services, etc. A stored completed invocation can also be purged","operationId":"delete_invocation","parameters":[{"name":"invocation_id","in":"path","description":"Invocation identifier.","required":true,"schema":{"type":"string"}},{"name":"mode","in":"query","description":"If cancel, it will gracefully terminate the invocation. If kill, it will terminate the invocation with a hard stop. If purge, it will only cleanup the response for completed invocations, and leave unaffected an in-flight invocation.","style":"simple","schema":{"$ref":"#/components/schemas/DeletionMode"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/state":{"post":{"tags":["service"],"summary":"Modify a service state","description":"Modify service state","operationId":"modify_service_state","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceStateRequest"}}},"required":true},"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}}},"components":{"schemas":{"ListDeploymentsResponse":{"type":"object","required":["deployments"],"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentResponse"}}}},"DeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceNameRevPair"}}}},"String":{"type":"string"},"ServiceNameRevPair":{"type":"object","required":["name","revision"],"properties":{"name":{"type":"string"},"revision":{"type":"integer","format":"uint32","minimum":0.0}}},"ProtocolType":{"type":"string","enum":["RequestResponse","BidiStream"]},"LambdaARN":{"type":"string","format":"arn"},"SubscriptionResponse":{"type":"object","required":["id","options","sink","source"],"properties":{"id":{"$ref":"#/components/schemas/String"},"source":{"type":"string"},"sink":{"type":"string"},"options":{"type":"object","additionalProperties":{"type":"string"}}}},"ErrorDescriptionResponse":{"title":"Error description response","description":"Error details of the response","type":"object","required":["message"],"properties":{"message":{"type":"string"},"restate_code":{"title":"Restate code","description":"Restate error code describing this error","type":"string","nullable":true}}},"ListServicesResponse":{"type":"object","required":["services"],"properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ServiceMetadata":{"type":"object","required":["deployment_id","handlers","idempotency_retention","name","public","revision","ty"],"properties":{"name":{"title":"Name","description":"Fully qualified name of the service","type":"string"},"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}},"ty":{"$ref":"#/components/schemas/ServiceType"},"deployment_id":{"title":"Deployment Id","description":"Deployment exposing the latest revision of the service.","type":"string"},"revision":{"title":"Revision","description":"Latest revision of the service.","type":"integer","format":"uint32","minimum":0.0},"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","type":"boolean"},"idempotency_retention":{"title":"Idempotency retention","description":"The retention duration of idempotent requests for this service.","type":"string"},"workflow_completion_retention":{"title":"Workflow completion retention","description":"The retention duration of workflows. Only available on workflow services.","type":"string","nullable":true}}},"HandlerMetadata":{"type":"object","required":["input_description","name","output_description","ty"],"properties":{"name":{"type":"string"},"ty":{"$ref":"#/components/schemas/HandlerMetadataType"},"input_description":{"type":"string"},"output_description":{"type":"string"}}},"HandlerMetadataType":{"type":"string","enum":["Exclusive","Shared","Workflow"]},"ServiceType":{"type":"string","enum":["Service","VirtualObject","Workflow"]},"ListServiceHandlersResponse":{"type":"object","required":["handlers"],"properties":{"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"DetailedDeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"CreateSubscriptionRequest":{"type":"object","required":["sink","source"],"properties":{"source":{"title":"Source","description":"Source uri. Accepted forms:\n\n* `kafka:///`, e.g. `kafka://my-cluster/my-topic`","type":"string"},"sink":{"title":"Sink","description":"Sink uri. Accepted forms:\n\n* `service:///`, e.g. `service://Counter/count`","type":"string"},"options":{"title":"Options","description":"Additional options to apply to the subscription.","type":"object","additionalProperties":{"type":"string"},"nullable":true}}},"ModifyServiceRequest":{"type":"object","properties":{"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","type":"boolean","nullable":true},"idempotency_retention":{"title":"Idempotency retention","description":"Modify the retention of idempotent requests for this service.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","type":"string","nullable":true},"workflow_completion_retention":{"title":"Workflow completion retention","description":"Modify the retention of the workflow completion. This can be modified only for workflow services!\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","type":"string","nullable":true}}},"VersionInformation":{"type":"object","required":["max_admin_api_version","min_admin_api_version","version"],"properties":{"version":{"title":"Admin server version","description":"Version of the admin server","type":"string"},"min_admin_api_version":{"title":"Min admin API version","description":"Minimum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0},"max_admin_api_version":{"title":"Max admin API version","description":"Maximum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0}}},"ListSubscriptionsResponse":{"type":"object","required":["subscriptions"],"properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"DeletionMode":{"type":"string","enum":["Cancel","Kill","Purge"]},"RegisterDeploymentRequest":{"anyOf":[{"type":"object","required":["uri"],"properties":{"uri":{"title":"Uri","description":"Uri to use to discover/invoke the http deployment.","type":"string"},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}},{"type":"object","required":["arn"],"properties":{"arn":{"title":"ARN","description":"ARN to use to discover/invoke the lambda deployment.","type":"string"},"assume_role_arn":{"title":"Assume role ARN","description":"Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining","type":"string","nullable":true},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}}]},"RegisterDeploymentResponse":{"type":"object","required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ModifyServiceStateRequest":{"type":"object","required":["new_state","object_key"],"properties":{"version":{"title":"Version","description":"If set, the latest version of the state is compared with this value and the operation will fail when the versions differ.","type":"string","nullable":true},"object_key":{"title":"Service key","description":"To what virtual object key to apply this change","type":"string"},"new_state":{"title":"New State","description":"The new state to replace the previous state with","type":"object","additionalProperties":{"type":"array","items":{"type":"integer","format":"uint8","minimum":0.0}}}}}}}} +{"openapi":"3.0.0","info":{"title":"Admin API","version":"1.1.0"},"paths":{"/health":{"get":{"tags":["health"],"summary":"Health check","description":"Check REST API Health.","operationId":"health","responses":{"200":{"description":"OK"}}}},"/subscriptions/{subscription}":{"get":{"tags":["subscription"],"summary":"Get subscription","description":"Get subscription","operationId":"get_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["subscription"],"summary":"Delete subscription","description":"Delete subscription.","operationId":"delete_subscription","parameters":[{"name":"subscription","in":"path","description":"Subscription identifier","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers/{handler}":{"get":{"tags":["service_handler"],"summary":"Get service handler","description":"Get the handler of a service","operationId":"get_service_handler","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}},{"name":"handler","in":"path","description":"Handler name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments/{deployment}":{"get":{"tags":["deployment"],"summary":"Get deployment","description":"Get deployment metadata","operationId":"get_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"delete":{"tags":["deployment"],"summary":"Delete deployment","description":"Delete deployment. Currently it's supported to remove a deployment only using the force flag","operationId":"delete_deployment","parameters":[{"name":"deployment","in":"path","description":"Deployment identifier","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","description":"If true, the deployment will be forcefully deleted. This might break in-flight invocations, use with caution.","style":"simple","schema":{"type":"boolean"}}],"responses":{"202":{"description":"Accepted"},"501":{"description":"Not implemented. Only using the force flag is supported at the moment."},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/deployments":{"get":{"tags":["deployment"],"summary":"List deployments","description":"List all registered deployments.","operationId":"list_deployments","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDeploymentsResponse"}}}}}},"post":{"tags":["deployment"],"summary":"Create deployment","description":"Create deployment. Restate will invoke the endpoint to gather additional information required for registration, such as the services exposed by the deployment. If the deployment is already registered, this method will fail unless `force` is set to `true`.","operationId":"create_deployment","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeploymentResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/subscriptions":{"get":{"tags":["subscription"],"summary":"List subscriptions","description":"List all subscriptions.","operationId":"list_subscriptions","parameters":[{"name":"sink","in":"query","description":"Filter by the exact specified sink.","style":"simple","schema":{"type":"string"}},{"name":"source","in":"query","description":"Filter by the exact specified source.","style":"simple","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSubscriptionsResponse"}}}}}},"post":{"tags":["subscription"],"summary":"Create subscription","description":"Create subscription.","operationId":"create_subscription","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionRequest"}}},"required":true},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/invocations/{invocation_id}":{"delete":{"tags":["invocation"],"summary":"Delete an invocation","description":"Delete the given invocation. By default, an invocation is terminated by gracefully cancelling it. This ensures virtual object state consistency. Alternatively, an invocation can be killed which does not guarantee consistency for virtual object instance state, in-flight invocations to other services, etc. A stored completed invocation can also be purged","operationId":"delete_invocation","parameters":[{"name":"invocation_id","in":"path","description":"Invocation identifier.","required":true,"schema":{"type":"string"}},{"name":"mode","in":"query","description":"If cancel, it will gracefully terminate the invocation. If kill, it will terminate the invocation with a hard stop. If purge, it will only cleanup the response for completed invocations, and leave unaffected an in-flight invocation.","style":"simple","schema":{"$ref":"#/components/schemas/DeletionMode"}}],"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}":{"get":{"tags":["service"],"summary":"Get service","description":"Get a registered service.","operationId":"get_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}},"patch":{"tags":["service"],"summary":"Modify a service","description":"Modify a registered service.","operationId":"modify_service","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services/{service}/handlers":{"get":{"tags":["service_handler"],"summary":"List service handlers","description":"List all the handlers of the given service.","operationId":"list_service_handlers","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServiceHandlersResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/services":{"get":{"tags":["service"],"summary":"List services","description":"List all registered services.","operationId":"list_services","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListServicesResponse"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/version":{"get":{"tags":["version"],"summary":"Admin version information","description":"Obtain admin version information.","operationId":"version","responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionInformation"}}}}}}},"/services/{service}/state":{"post":{"tags":["service"],"summary":"Modify a service state","description":"Modify service state","operationId":"modify_service_state","parameters":[{"name":"service","in":"path","description":"Fully qualified service name.","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModifyServiceStateRequest"}}},"required":true},"responses":{"202":{"description":"Accepted"},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"403":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"404":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"409":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"500":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}},"503":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDescriptionResponse"}}}}}}},"/openapi":{"get":{"tags":["openapi"],"summary":"OpenAPI specification","externalDocs":{"url":"https://swagger.io/specification/"},"operationId":"openapi_spec","responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}}}}}}},"components":{"schemas":{"SubscriptionResponse":{"type":"object","required":["id","options","sink","source"],"properties":{"id":{"$ref":"#/components/schemas/String"},"source":{"type":"string"},"sink":{"type":"string"},"options":{"type":"object","additionalProperties":{"type":"string"}}}},"String":{"type":"string"},"ErrorDescriptionResponse":{"title":"Error description response","description":"Error details of the response","type":"object","required":["message"],"properties":{"message":{"type":"string"},"restate_code":{"title":"Restate code","description":"Restate error code describing this error","type":"string","nullable":true}}},"HandlerMetadata":{"type":"object","required":["input_description","name","output_description","ty"],"properties":{"name":{"type":"string"},"ty":{"$ref":"#/components/schemas/HandlerMetadataType"},"input_description":{"type":"string"},"output_description":{"type":"string"}}},"HandlerMetadataType":{"type":"string","enum":["Exclusive","Shared","Workflow"]},"RegisterDeploymentRequest":{"anyOf":[{"type":"object","required":["uri"],"properties":{"uri":{"title":"Uri","description":"Uri to use to discover/invoke the http deployment.","type":"string"},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"use_http_11":{"title":"Use http1.1","description":"If `true`, discovery will be attempted using a client that defaults to HTTP1.1 instead of a prior-knowledge HTTP2 client. HTTP2 may still be used for TLS servers that advertise HTTP2 support via ALPN. HTTP1.1 deployments will only work in request-response mode.","default":false,"type":"boolean"},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}},{"type":"object","required":["arn"],"properties":{"arn":{"title":"ARN","description":"ARN to use to discover/invoke the lambda deployment.","type":"string"},"assume_role_arn":{"title":"Assume role ARN","description":"Optional ARN of a role to assume when invoking the addressed Lambda, to support role chaining","type":"string","nullable":true},"additional_headers":{"title":"Additional headers","description":"Additional headers added to the discover/invoke requests to the deployment.","type":"object","additionalProperties":{"type":"string"},"nullable":true},"force":{"title":"Force","description":"If `true`, it will override, if existing, any deployment using the same `uri`. Beware that this can lead in-flight invocations to an unrecoverable error state.\n\nBy default, this is `true` but it might change in future to `false`.\n\nSee the [versioning documentation](https://docs.restate.dev/operate/versioning) for more information.","default":true,"type":"boolean"},"dry_run":{"title":"Dry-run mode","description":"If `true`, discovery will run but the deployment will not be registered. This is useful to see the impact of a new deployment before registering it.","default":false,"type":"boolean"}}}]},"RegisterDeploymentResponse":{"type":"object","required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ServiceMetadata":{"type":"object","required":["deployment_id","handlers","idempotency_retention","name","public","revision","ty"],"properties":{"name":{"title":"Name","description":"Fully qualified name of the service","type":"string"},"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}},"ty":{"$ref":"#/components/schemas/ServiceType"},"deployment_id":{"title":"Deployment Id","description":"Deployment exposing the latest revision of the service.","type":"string"},"revision":{"title":"Revision","description":"Latest revision of the service.","type":"integer","format":"uint32","minimum":0.0},"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","type":"boolean"},"idempotency_retention":{"title":"Idempotency retention","description":"The retention duration of idempotent requests for this service.","type":"string"},"workflow_completion_retention":{"title":"Workflow completion retention","description":"The retention duration of workflows. Only available on workflow services.","type":"string","nullable":true}}},"ServiceType":{"type":"string","enum":["Service","VirtualObject","Workflow"]},"CreateSubscriptionRequest":{"type":"object","required":["sink","source"],"properties":{"source":{"title":"Source","description":"Source uri. Accepted forms:\n\n* `kafka:///`, e.g. `kafka://my-cluster/my-topic`","type":"string"},"sink":{"title":"Sink","description":"Sink uri. Accepted forms:\n\n* `service:///`, e.g. `service://Counter/count`","type":"string"},"options":{"title":"Options","description":"Additional options to apply to the subscription.","type":"object","additionalProperties":{"type":"string"},"nullable":true}}},"DeletionMode":{"type":"string","enum":["Cancel","Kill","Purge"]},"DetailedDeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","http_version","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"http_version":{"type":"string"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"ProtocolType":{"type":"string","enum":["RequestResponse","BidiStream"]},"LambdaARN":{"type":"string","format":"arn"},"ListDeploymentsResponse":{"type":"object","required":["deployments"],"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/DeploymentResponse"}}}},"DeploymentResponse":{"type":"object","anyOf":[{"type":"object","required":["created_at","http_version","max_protocol_version","min_protocol_version","protocol_type","uri"],"properties":{"uri":{"type":"string"},"protocol_type":{"$ref":"#/components/schemas/ProtocolType"},"http_version":{"type":"string"},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}},{"type":"object","required":["arn","created_at","max_protocol_version","min_protocol_version"],"properties":{"arn":{"$ref":"#/components/schemas/LambdaARN"},"assume_role_arn":{"type":"string","nullable":true},"additional_headers":{"type":"object","additionalProperties":{"type":"string"}},"created_at":{"type":"string"},"min_protocol_version":{"type":"integer","format":"int32"},"max_protocol_version":{"type":"integer","format":"int32"}}}],"required":["id","services"],"properties":{"id":{"$ref":"#/components/schemas/String"},"services":{"title":"Services","description":"List of services exposed by this deployment.","type":"array","items":{"$ref":"#/components/schemas/ServiceNameRevPair"}}}},"ServiceNameRevPair":{"type":"object","required":["name","revision"],"properties":{"name":{"type":"string"},"revision":{"type":"integer","format":"uint32","minimum":0.0}}},"ModifyServiceRequest":{"type":"object","properties":{"public":{"title":"Public","description":"If true, the service can be invoked through the ingress. If false, the service can be invoked only from another Restate service.","type":"boolean","nullable":true},"idempotency_retention":{"title":"Idempotency retention","description":"Modify the retention of idempotent requests for this service.\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","type":"string","nullable":true},"workflow_completion_retention":{"title":"Workflow completion retention","description":"Modify the retention of the workflow completion. This can be modified only for workflow services!\n\nCan be configured using the [`humantime`](https://docs.rs/humantime/latest/humantime/fn.parse_duration.html) format or the ISO8601.","type":"string","nullable":true}}},"ListServiceHandlersResponse":{"type":"object","required":["handlers"],"properties":{"handlers":{"type":"array","items":{"$ref":"#/components/schemas/HandlerMetadata"}}}},"ListServicesResponse":{"type":"object","required":["services"],"properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/ServiceMetadata"}}}},"VersionInformation":{"type":"object","required":["max_admin_api_version","min_admin_api_version","version"],"properties":{"version":{"title":"Admin server version","description":"Version of the admin server","type":"string"},"min_admin_api_version":{"title":"Min admin API version","description":"Minimum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0},"max_admin_api_version":{"title":"Max admin API version","description":"Maximum supported admin API version by the admin server","type":"integer","format":"uint16","minimum":0.0}}},"ModifyServiceStateRequest":{"type":"object","required":["new_state","object_key"],"properties":{"version":{"title":"Version","description":"If set, the latest version of the state is compared with this value and the operation will fail when the versions differ.","type":"string","nullable":true},"object_key":{"title":"Service key","description":"To what virtual object key to apply this change","type":"string"},"new_state":{"title":"New State","description":"The new state to replace the previous state with","type":"object","additionalProperties":{"type":"array","items":{"type":"integer","format":"uint8","minimum":0.0}}}}},"ListSubscriptionsResponse":{"type":"object","required":["subscriptions"],"properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionResponse"}}}}}}} diff --git a/static/schemas/restate.toml b/static/schemas/restate.toml index e3a718af..2dfb3bf0 100644 --- a/static/schemas/restate.toml +++ b/static/schemas/restate.toml @@ -5,7 +5,6 @@ roles = [ ] cluster-name = "localcluster" allow-bootstrap = true -metadata-store-address = "http://127.0.0.1:5123/" bind-address = "0.0.0.0:5122" advertised-address = "http://127.0.0.1:5122/" bootstrap-num-partitions = 24 @@ -22,13 +21,36 @@ rocksdb-high-priority-bg-threads = 2 rocksdb-write-stall-threshold = "3s" rocksdb-enable-stall-on-memory-limit = false rocksdb-perf-level = "enable-count" +metadata-update-interval = "3s" + +[metadata-store-client] +type = "embedded" +address = "http://127.0.0.1:5123/" + +[metadata-store-client-backoff-policy] +type = "exponential" +initial-interval = "10ms" +factor = 2.0 +max-interval = "100ms" + +[tracing-headers] [http-keep-alive-options] interval = "40s" timeout = "20s" +[network-error-retry-policy] +type = "exponential" +initial-interval = "10ms" +factor = 2.0 +max-attempts = 15 +max-interval = "5s" + [worker] -internal-queue-length = 10000 +internal-queue-length = 1000 +cleanup-interval = "1h" +experimental-feature-new-invocation-status-table = false +max-command-batch-size = 4 [worker.storage] rocksdb-disable-wal = true @@ -40,7 +62,8 @@ persist-lsn-threshold = 1000 inactivity-timeout = "1m" abort-timeout = "1m" message-size-warning = "10.0 MB" -concurrent-invocations-limit = 10000 +in-memory-queue-length-limit = 1056784 +concurrent-invocations-limit = 100 [worker.invoker.retry-policy] type = "exponential" @@ -53,6 +76,7 @@ bind-address = "0.0.0.0:9070" heartbeat-interval = "1s 500ms" log-trim-interval = "1h" log-trim-threshold = 1000 +default-replication-strategy = "on-all-nodes" [admin.query-engine] memory-size = "4.0 GB" @@ -64,6 +88,9 @@ kafka-clusters = [] [bifrost] default-provider = "local" +seal-retry-interval = "2s" +append-retry-min-interval = "10ms" +append-retry-max-interval = "1s" [bifrost.local] rocksdb-disable-wal = false @@ -72,6 +99,13 @@ rocksdb-disable-wal-fsync = false writer-batch-commit-count = 5000 writer-batch-commit-duration = "0s" +[bifrost.read-retry-policy] +type = "exponential" +initial-interval = "50ms" +factor = 2.0 +max-attempts = 50 +max-interval = "1s" + [metadata-store] bind-address = "0.0.0.0:5123" request-queue-length = 32 @@ -80,3 +114,20 @@ rocksdb-memory-ratio = 0.009999999776482582 [metadata-store.rocksdb] rocksdb-disable-wal = false +[networking] +handshake-timeout = "3s" + +[networking.connect-retry-policy] +type = "exponential" +initial-interval = "10ms" +factor = 2.0 +max-attempts = 10 +max-interval = "500ms" + +[log-server] +rocksdb-disable-wal = false +rocksdb-memory-ratio = 0.5 +rocksdb-disable-wal-fsync = false +writer-batch-commit-count = 5000 +incoming-network-queue-length = 1000 +