Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Initial version of golem:[email protected] with oplog enumeration #29

Merged
merged 12 commits into from
Oct 9, 2024
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
264 changes: 264 additions & 0 deletions wit/deps/golem-1.1/golem-host-1.1.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
// UNSTABLE API - WILL BE CHANGING UNTIL THE GOLEM 1.1 RELEASE
//
// BACKWARD COMPATIBILITY GUARANTEES ARE NOT APPLIED TO WORKERS USING THIS HOST INTERFACE

package golem:[email protected];

/// The Golem host API provides low level access to Golem specific features such as promises and control over
/// the durability and transactional guarantees the executor provides.
interface host {
use golem:rpc/[email protected].{uri};
use wasi:clocks/[email protected].{duration};

/// An index into the persistent log storing all performed operations of a worker
type oplog-index = u64;

/// A promise ID is a value that can be passed to an external Golem API to complete that promise
/// from an arbitrary external source, while Golem workers can await for this completion.
record promise-id {
worker-id: worker-id,
oplog-idx: oplog-index,
}

/// Represents a Golem worker
record worker-id {
component-id: component-id,
worker-name: string
}

/// Represents a Golem component
record component-id {
uuid: uuid,
}

/// Represents a Golem component's version
type component-version = u64;

/// UUID
record uuid {
high-bits: u64,
low-bits: u64
}

/// Represents a Golem Cloud account
record account-id {
value: string
}

/// Configures how the executor retries failures
record retry-policy {
/// The maximum number of retries before the worker becomes permanently failed
max-attempts: u32,
/// The minimum delay between retries (applied to the first retry)
min-delay: duration,
/// The maximum delay between retries
max-delay: duration,
/// Multiplier applied to the delay on each retry to implement exponential backoff
multiplier: f64,
/// The maximum amount of jitter to add to the delay
max-jitter-factor: option<f64>
}

/// Configurable persistence level for workers
variant persistence-level {
persist-nothing,
persist-remote-side-effects,
smart
}

/// Describes how to update a worker to a different component version
enum update-mode {
/// Automatic update tries to recover the worker using the new component version
/// and may fail if there is a divergence.
automatic,

/// Manual, snapshot-based update uses a user-defined implementation of the `save-snapshot` interface
/// to store the worker's state, and a user-defined implementation of the `load-snapshot` interface to
/// load it into the new version.
snapshot-based
}

enum filter-comparator {
equal,
not-equal,
greater-equal,
greater,
less-equal,
less
}

enum string-filter-comparator {
equal,
not-equal,
like,
not-like
}

enum worker-status {
/// The worker is running an invoked function
running,
/// The worker is ready to run an invoked function
idle,
/// An invocation is active but waiting for something (sleeping, waiting for a promise)
suspended,
/// The last invocation was interrupted but will be resumed
interrupted,
/// The last invocation failed and a retry was scheduled
retrying,
/// The last invocation failed and the worker can no longer be used
failed,
/// The worker exited after a successful invocation and can no longer be invoked
exited,
}

record worker-name-filter {
comparator: string-filter-comparator,
value: string
}

record worker-status-filter {
comparator: filter-comparator,
value: worker-status
}

record worker-version-filter {
comparator: filter-comparator,
value: u64
}

record worker-created-at-filter {
comparator: filter-comparator,
value: u64
}

record worker-env-filter {
name: string,
comparator: string-filter-comparator,
value: string
}

variant worker-property-filter {
name(worker-name-filter),
status(worker-status-filter),
version(worker-version-filter),
created-at(worker-created-at-filter),
env(worker-env-filter)
}

record worker-all-filter {
filters: list<worker-property-filter>
}

record worker-any-filter {
filters: list<worker-all-filter>
}

record worker-metadata {
worker-id: worker-id,
args: list<string>,
env: list<tuple<string, string>>,
status: worker-status,
component-version: u64,
retry-count: u64
}

resource get-workers {
constructor(component-id: component-id, filter: option<worker-any-filter>, precise: bool);

get-next: func() -> option<list<worker-metadata>>;
}

/// Create a new promise
create-promise: func() -> promise-id;

/// Suspends execution until the given promise gets completed, and returns the payload passed to
/// the promise completion.
await-promise: func(promise-id: promise-id) -> list<u8>;

/// Completes the given promise with the given payload. Returns true if the promise was completed, false
/// if the promise was already completed. The payload is passed to the worker that is awaiting the promise.
complete-promise: func(promise-id: promise-id, data: list<u8>) -> bool;

/// Deletes the given promise
delete-promise: func(promise-id: promise-id) -> ();

/// Returns the current position in the persistent op log
get-oplog-index: func() -> oplog-index;

/// Makes the current worker travel back in time and continue execution from the given position in the persistent
/// op log.
set-oplog-index: func(oplog-idx: oplog-index) -> ();

/// Blocks the execution until the oplog has been written to at least the specified number of replicas,
/// or the maximum number of replicas if the requested number is higher.
oplog-commit: func(replicas: u8) -> ();

/// Marks the beginning of an atomic operation.
/// In case of a failure within the region selected by `mark-begin-operation` and `mark-end-operation`
/// the whole region will be reexecuted on retry.
/// The end of the region is when `mark-end-operation` is called with the returned oplog-index.
mark-begin-operation: func() -> oplog-index;

/// Commits this atomic operation. After `mark-end-operation` is called for a given index, further calls
/// with the same parameter will do nothing.
mark-end-operation: func(begin: oplog-index) -> ();

/// Gets the current retry policy associated with the worker
get-retry-policy: func() -> retry-policy;

/// Overrides the current retry policy associated with the worker. Following this call, `get-retry-policy` will return the
/// new retry policy.
set-retry-policy: func(new-retry-policy: retry-policy) -> ();

/// Gets the worker's current persistence level.
get-oplog-persistence-level: func() -> persistence-level;

/// Sets the worker's current persistence level. This can increase the performance of execution in cases where durable
/// execution is not required.
set-oplog-persistence-level: func(new-persistence-level: persistence-level) -> ();

/// Gets the current idempotence mode. See `set-idempotence-mode` for details.
get-idempotence-mode: func() -> bool;

/// Sets the current idempotence mode. The default is true.
/// True means side-effects are treated idempotent and Golem guarantees at-least-once semantics.
/// In case of false the executor provides at-most-once semantics, failing the worker in case it is
/// not known if the side effect was already executed.
set-idempotence-mode: func(idempotent: bool) -> ();

/// Generates an idempotency key. This operation will never be replayed —
/// i.e. not only is this key generated, but it is persisted and committed, such that the key can be used in third-party systems (e.g. payment processing)
/// to introduce idempotence.
generate-idempotency-key: func() -> uuid;

/// Initiates an update attempt for the given worker. The function returns immediately once the request has been processed,
/// not waiting for the worker to get updated.
update-worker: func(worker-id: worker-id, target-version: component-version, mode: update-mode) -> ();

/// Get current worker metadata
get-self-metadata: func() -> worker-metadata;

/// Get worker metadata
get-worker-metadata: func(worker-id: worker-id) -> option<worker-metadata>;
}

/// Interface providing user-defined snapshotting capability. This can be used to perform manual update of workers
/// when the new component incompatible with the old one.
interface save-snapshot {
/// Saves the component's state into a user-defined snapshot
save: func() -> list<u8>;
}

/// Interface providing user-defined snapshotting capability. This can be used to perform manual update of workers
/// when the new component incompatible with the old one.
interface load-snapshot {
/// Tries to load a user-defined snapshot, setting up the worker's state based on it.
/// The function can return with a failure to indicate that the update is not possible.
load: func(bytes: list<u8>) -> result<_, string>;
}

world golem-host {
import host;
import save-snapshot;
import load-snapshot;
}
Loading
Loading