///|
fn utf8(s : String) -> Bytes {
@utf8.encode(s)
}
///|
fn utf8_lossy(bytes : Bytes) -> String {
@utf8.decode_lossy(bytes)
}
///|
fn temporal_error(result : CoreResult) -> TemporalError {
{ message: utf8_lossy(core_result_error_message(result)) }
}
///|
fn unit_result(result : CoreResult) -> Result[Unit, TemporalError] {
if core_result_is_ok(result) {
Ok(())
} else {
Err(temporal_error(result))
}
}
///|
/// Creates a Temporal Core runtime.
///
/// The runtime owns Core background resources used by connections, workers, and
/// ephemeral servers. Keep it alive for as long as those handles are in use.
pub fn Runtime::new(
options? : RuntimeOptions = RuntimeOptions::default(),
) -> Result[Runtime, TemporalError] {
let result = runtime_new_ffi(options.worker_heartbeat_interval_millis)
if core_result_is_ok(result) {
Ok(core_result_take_runtime(result))
} else {
Err(temporal_error(result))
}
}
///|
/// Connects to a Temporal endpoint and waits for Core to finish connection
/// setup.
pub fn Connection::connect_blocking(
runtime : Runtime,
options : ConnectionOptions,
) -> Result[Connection, TemporalError] {
let result = connection_connect_ffi(
runtime,
utf8(options.target_url),
utf8(options.client_name),
utf8(options.client_version),
utf8(options.identity),
utf8(options.api_key),
options.metadata,
options.binary_metadata,
)
if core_result_is_ok(result) {
Ok(core_result_take_connection(result))
} else {
Err(temporal_error(result))
}
}
///|
/// Callback-shaped connection helper.
///
/// This currently invokes `connect_blocking` and calls `callback` before
/// returning.
pub fn Connection::connect(
runtime : Runtime,
options : ConnectionOptions,
callback : (Result[Connection, TemporalError]) -> Unit,
) -> Unit {
callback(Connection::connect_blocking(runtime, options))
}
///|
/// Replaces the API key used by this connection for later calls.
pub fn Connection::update_api_key(self : Connection, api_key : String) -> Unit {
connection_update_api_key_ffi(self, utf8(api_key))
}
///|
/// Replaces textual gRPC metadata for later calls.
///
/// The byte format is newline-separated key/value pairs.
pub fn Connection::update_metadata(self : Connection, metadata : Bytes) -> Unit {
connection_update_metadata_ffi(self, metadata)
}
///|
/// Replaces binary gRPC metadata for later calls.
///
/// The byte format is newline-separated key/value pairs.
pub fn Connection::update_binary_metadata(
self : Connection,
metadata : Bytes,
) -> Unit {
connection_update_binary_metadata_ffi(self, metadata)
}
///|
/// Performs a raw Temporal RPC call and waits for the encoded protobuf
/// response.
pub fn Connection::rpc_call_blocking(
self : Connection,
options : RpcCallOptions,
) -> Result[Bytes, RpcFailure] {
let rpc = utf8(options.rpc)
let result = match options.cancellation_token {
Some(token) =>
connection_rpc_call_with_cancel_ffi(
self,
options.service.to_int(),
rpc,
options.request,
options.retry,
options.metadata,
options.binary_metadata,
options.timeout_millis,
token,
)
None =>
connection_rpc_call_ffi(
self,
options.service.to_int(),
rpc,
options.request,
options.retry,
options.metadata,
options.binary_metadata,
options.timeout_millis,
)
}
if core_result_is_ok(result) {
Ok(core_result_success_bytes(result))
} else {
Err({
status_code: core_result_status_code(result),
message: utf8_lossy(core_result_error_message(result)),
details: core_result_failure_details(result),
})
}
}
///|
/// Callback-shaped raw RPC helper.
///
/// This currently invokes `rpc_call_blocking` and calls `callback` before
/// returning.
pub fn Connection::rpc_call(
self : Connection,
options : RpcCallOptions,
callback : (Result[Bytes, RpcFailure]) -> Unit,
) -> Unit {
callback(self.rpc_call_blocking(options))
}
///|
/// Creates a cancellation token that can be attached to `RpcCallOptions`.
pub fn CancellationToken::new() -> CancellationToken {
cancellation_token_new_ffi()
}
///|
/// Requests cancellation for operations using this token.
pub fn CancellationToken::cancel(self : CancellationToken) -> Unit {
cancellation_token_cancel_ffi(self)
}
///|
/// Creates a deterministic random source using `seed`.
pub fn Random::new(seed : UInt64) -> Random {
random_new_ffi(seed)
}
///|
/// Returns a deterministic integer in the configured range.
///
/// With the default `max_inclusive = false`, the range is `[min, max)`.
pub fn Random::int32_range(
self : Random,
min : Int,
max : Int,
max_inclusive? : Bool = false,
) -> Int {
random_int32_range_ffi(self, min, max, max_inclusive)
}
///|
/// Returns a deterministic floating-point value in the configured range.
///
/// With the default `max_inclusive = false`, the range is `[min, max)`.
pub fn Random::double_range(
self : Random,
min : Double,
max : Double,
max_inclusive? : Bool = false,
) -> Double {
random_double_range_ffi(self, min, max, max_inclusive)
}
///|
/// Returns `len` deterministic random bytes.
pub fn Random::fill_bytes(self : Random, len : Int) -> Bytes {
random_fill_bytes_ffi(self, len)
}
///|
/// Creates a Core worker bound to `connection`.
pub fn Worker::new(
connection : Connection,
options : WorkerOptions,
) -> Result[Worker, TemporalError] {
let task_types = options.task_types
let result = worker_new_ffi(
connection,
utf8(options.namespace_name),
utf8(options.task_queue),
utf8(options.build_id),
utf8(options.identity_override),
options.max_cached_workflows,
options.workflow_slots,
options.activity_slots,
options.local_activity_slots,
options.nexus_slots,
task_types.enable_workflows,
task_types.enable_local_activities,
task_types.enable_remote_activities,
task_types.enable_nexus,
options.sticky_queue_schedule_to_start_timeout_millis,
options.max_heartbeat_throttle_interval_millis,
options.default_heartbeat_throttle_interval_millis,
options.max_activities_per_second,
options.max_task_queue_activities_per_second,
options.graceful_shutdown_period_millis,
options.workflow_task_poller_behavior.simple_maximum,
options.nonsticky_to_sticky_poll_ratio,
options.activity_task_poller_behavior.simple_maximum,
options.nexus_task_poller_behavior.simple_maximum,
options.nondeterminism_as_workflow_fail,
)
if core_result_is_ok(result) {
Ok(core_result_take_worker(result))
} else {
Err(temporal_error(result))
}
}
///|
/// Validates the worker configuration with Temporal Core.
pub fn Worker::validate_blocking(self : Worker) -> Result[Unit, TemporalError] {
unit_result(worker_validate_ffi(self))
}
///|
/// Callback-shaped worker validation helper.
///
/// This currently invokes `validate_blocking` and calls `callback` before
/// returning.
pub fn Worker::validate(
self : Worker,
callback : (Result[Unit, TemporalError]) -> Unit,
) -> Unit {
callback(self.validate_blocking())
}
///|
/// Replaces the client connection used by this worker.
pub fn Worker::replace_client(
self : Worker,
connection : Connection,
) -> Result[Unit, TemporalError] {
unit_result(worker_replace_client_ffi(self, connection))
}
///|
/// Polls for the next workflow activation.
///
/// Returns `Ok(None)` when the worker has shut down. Otherwise the returned
/// bytes are an encoded Core workflow activation protobuf.
pub fn Worker::poll_workflow_activation_blocking(
self : Worker,
) -> Result[Bytes?, TemporalError] {
let result = worker_poll_workflow_activation_ffi(self)
if core_result_is_ok(result) {
if core_result_is_shutdown(result) {
Ok(None)
} else {
Ok(Some(core_result_success_bytes(result)))
}
} else {
Err(temporal_error(result))
}
}
///|
/// Callback-shaped workflow activation poll helper.
///
/// This currently invokes `poll_workflow_activation_blocking` and calls
/// `callback` before returning.
pub fn Worker::poll_workflow_activation(
self : Worker,
callback : (Result[Bytes?, TemporalError]) -> Unit,
) -> Unit {
callback(self.poll_workflow_activation_blocking())
}
///|
/// Polls for the next activity task.
///
/// Returns `Ok(None)` when the worker has shut down. Otherwise the returned
/// bytes are an encoded Core activity task protobuf.
pub fn Worker::poll_activity_task_blocking(
self : Worker,
) -> Result[Bytes?, TemporalError] {
let result = worker_poll_activity_task_ffi(self)
if core_result_is_ok(result) {
if core_result_is_shutdown(result) {
Ok(None)
} else {
Ok(Some(core_result_success_bytes(result)))
}
} else {
Err(temporal_error(result))
}
}
///|
/// Callback-shaped activity task poll helper.
///
/// This currently invokes `poll_activity_task_blocking` and calls `callback`
/// before returning.
pub fn Worker::poll_activity_task(
self : Worker,
callback : (Result[Bytes?, TemporalError]) -> Unit,
) -> Unit {
callback(self.poll_activity_task_blocking())
}
///|
/// Polls for the next Nexus task.
///
/// Returns `Ok(None)` when the worker has shut down. Otherwise the returned
/// bytes are an encoded Core Nexus task protobuf.
pub fn Worker::poll_nexus_task_blocking(
self : Worker,
) -> Result[Bytes?, TemporalError] {
let result = worker_poll_nexus_task_ffi(self)
if core_result_is_ok(result) {
if core_result_is_shutdown(result) {
Ok(None)
} else {
Ok(Some(core_result_success_bytes(result)))
}
} else {
Err(temporal_error(result))
}
}
///|
/// Callback-shaped Nexus task poll helper.
///
/// This currently invokes `poll_nexus_task_blocking` and calls `callback`
/// before returning.
pub fn Worker::poll_nexus_task(
self : Worker,
callback : (Result[Bytes?, TemporalError]) -> Unit,
) -> Unit {
callback(self.poll_nexus_task_blocking())
}
///|
/// Completes a workflow activation with an encoded Core completion protobuf.
pub fn Worker::complete_workflow_activation_blocking(
self : Worker,
completion : Bytes,
) -> Result[Unit, TemporalError] {
unit_result(worker_complete_workflow_activation_ffi(self, completion))
}
///|
/// Callback-shaped workflow activation completion helper.
///
/// This currently invokes `complete_workflow_activation_blocking` and calls
/// `callback` before returning.
pub fn Worker::complete_workflow_activation(
self : Worker,
completion : Bytes,
callback : (Result[Unit, TemporalError]) -> Unit,
) -> Unit {
callback(self.complete_workflow_activation_blocking(completion))
}
///|
/// Completes an activity task with an encoded Core completion protobuf.
pub fn Worker::complete_activity_task_blocking(
self : Worker,
completion : Bytes,
) -> Result[Unit, TemporalError] {
unit_result(worker_complete_activity_task_ffi(self, completion))
}
///|
/// Callback-shaped activity task completion helper.
///
/// This currently invokes `complete_activity_task_blocking` and calls
/// `callback` before returning.
pub fn Worker::complete_activity_task(
self : Worker,
completion : Bytes,
callback : (Result[Unit, TemporalError]) -> Unit,
) -> Unit {
callback(self.complete_activity_task_blocking(completion))
}
///|
/// Completes a Nexus task with an encoded Core completion protobuf.
pub fn Worker::complete_nexus_task_blocking(
self : Worker,
completion : Bytes,
) -> Result[Unit, TemporalError] {
unit_result(worker_complete_nexus_task_ffi(self, completion))
}
///|
/// Callback-shaped Nexus task completion helper.
///
/// This currently invokes `complete_nexus_task_blocking` and calls `callback`
/// before returning.
pub fn Worker::complete_nexus_task(
self : Worker,
completion : Bytes,
callback : (Result[Unit, TemporalError]) -> Unit,
) -> Unit {
callback(self.complete_nexus_task_blocking(completion))
}
///|
/// Records an activity heartbeat using an encoded Core heartbeat protobuf.
pub fn Worker::record_activity_heartbeat(
self : Worker,
heartbeat : Bytes,
) -> Result[Unit, TemporalError] {
unit_result(worker_record_activity_heartbeat_ffi(self, heartbeat))
}
///|
/// Requests eviction for a workflow run id from the worker cache.
pub fn Worker::request_workflow_eviction(
self : Worker,
run_id : String,
) -> Unit {
worker_request_workflow_eviction_ffi(self, utf8(run_id))
}
///|
/// Starts graceful worker shutdown.
pub fn Worker::initiate_shutdown(self : Worker) -> Unit {
worker_initiate_shutdown_ffi(self)
}
///|
/// Waits for worker shutdown to finish.
pub fn Worker::finalize_shutdown_blocking(
self : Worker,
) -> Result[Unit, TemporalError] {
unit_result(worker_finalize_shutdown_ffi(self))
}
///|
/// Callback-shaped shutdown finalization helper.
///
/// This currently invokes `finalize_shutdown_blocking` and calls `callback`
/// before returning.
pub fn Worker::finalize_shutdown(
self : Worker,
callback : (Result[Unit, TemporalError]) -> Unit,
) -> Unit {
callback(self.finalize_shutdown_blocking())
}
///|
/// Starts an ephemeral Temporal test server and returns its target address.
pub fn EphemeralServer::start_test_server_blocking(
runtime : Runtime,
options? : TestServerOptions = TestServerOptions::default(),
) -> Result[(EphemeralServer, String), TemporalError] {
let result = ephemeral_start_test_server_ffi(
runtime,
utf8(options.existing_path),
utf8(options.sdk_name),
utf8(options.sdk_version),
utf8(options.download_version),
utf8(options.download_dest_dir),
options.port,
utf8(options.extra_args),
options.download_ttl_seconds,
)
if core_result_is_ok(result) {
Ok(
(
core_result_take_ephemeral_server(result),
utf8_lossy(core_result_target(result)),
),
)
} else {
Err(temporal_error(result))
}
}
///|
/// Callback-shaped test server startup helper.
///
/// This currently invokes `start_test_server_blocking` and calls `callback`
/// before returning.
pub fn EphemeralServer::start_test_server(
runtime : Runtime,
options : TestServerOptions,
callback : (Result[(EphemeralServer, String), TemporalError]) -> Unit,
) -> Unit {
callback(EphemeralServer::start_test_server_blocking(runtime, options~))
}
///|
/// Starts an ephemeral Temporal development server and returns its target
/// address.
pub fn EphemeralServer::start_dev_server_blocking(
runtime : Runtime,
options? : DevServerOptions = DevServerOptions::default(),
) -> Result[(EphemeralServer, String), TemporalError] {
let test_server = options.test_server
let result = ephemeral_start_dev_server_ffi(
runtime,
utf8(test_server.existing_path),
utf8(test_server.sdk_name),
utf8(test_server.sdk_version),
utf8(test_server.download_version),
utf8(test_server.download_dest_dir),
test_server.port,
utf8(test_server.extra_args),
test_server.download_ttl_seconds,
utf8(options.namespace_name),
utf8(options.ip),
utf8(options.database_filename),
options.ui,
options.ui_port,
utf8(options.log_format),
utf8(options.log_level),
)
if core_result_is_ok(result) {
Ok(
(
core_result_take_ephemeral_server(result),
utf8_lossy(core_result_target(result)),
),
)
} else {
Err(temporal_error(result))
}
}
///|
/// Callback-shaped development server startup helper.
///
/// This currently invokes `start_dev_server_blocking` and calls `callback`
/// before returning.
pub fn EphemeralServer::start_dev_server(
runtime : Runtime,
options : DevServerOptions,
callback : (Result[(EphemeralServer, String), TemporalError]) -> Unit,
) -> Unit {
callback(EphemeralServer::start_dev_server_blocking(runtime, options~))
}
///|
/// Shuts down an ephemeral server and waits for it to finish.
pub fn EphemeralServer::shutdown_blocking(
self : EphemeralServer,
) -> Result[Unit, TemporalError] {
unit_result(ephemeral_server_shutdown_ffi(self))
}
///|
/// Callback-shaped ephemeral server shutdown helper.
///
/// This currently invokes `shutdown_blocking` and calls `callback` before
/// returning.
pub fn EphemeralServer::shutdown(
self : EphemeralServer,
callback : (Result[Unit, TemporalError]) -> Unit,
) -> Unit {
callback(self.shutdown_blocking())
}