### Worker Setup Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/README.md Example of setting up and starting a worker to execute workflows and activities. ```ruby worker = Temporal::Worker.new worker.register_workflow(MyWorkflow) worker.register_activity(FetchUserActivity) worker.start ``` -------------------------------- ### Starting a Worker Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Example code for initializing and starting a Temporal worker in Ruby. ```ruby require 'temporal/worker' worker = Temporal::Worker.new worker.register_workflow(HelloWorldWorkflow) worker.register_activity(SomeActivity) worker.register_activity(SomeOtherActivity) worker.start ``` -------------------------------- ### Install Gem Dependencies Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/README.md Installs all the gem dependencies required for the Temporal Ruby examples. ```sh bundle install ``` -------------------------------- ### Start Timer Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of starting a timer and waiting for it to fire. ```ruby timer = workflow.start_timer(30) # Do other work... timer.wait # Wait for timer to fire ``` -------------------------------- ### Start Temporal Server for Testing Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/README.md Starts the Temporal server using Docker Compose for running tests. ```sh docker-compose up ``` -------------------------------- ### Configuration Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/worker.md Example of configuring the Temporal connection, creating a worker, registering workflows and activities, adding middleware, and starting the worker. ```ruby require 'temporal/worker' # Configure Temporal connection Temporal.configure do |config| config.host = 'localhost' config.port = 7233 config.namespace = 'ruby-samples' config.task_queue = 'hello-world' end # Create worker worker = Temporal::Worker.new( activity_thread_pool_size: 20, workflow_thread_pool_size: 10, binary_checksum: 'v1.0.0' ) # Register workflows and activities worker.register_workflow(HelloWorldWorkflow) worker.register_activity(HelloActivity) # Add middleware class RequestIDPropagationMiddleware def initialize(request_id_header = 'X-Request-ID') @request_id_header = request_id_header end def call(metadata) request_id = metadata.headers[@request_id_header] RequestContext.set(request_id: request_id) if request_id yield ensure RequestContext.clear end end worker.add_activity_middleware(RequestIDPropagationMiddleware) # Start worker worker.start ``` -------------------------------- ### Execute activity synchronously example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of executing an activity synchronously and getting its result. ```ruby result = workflow.execute_activity!(MyActivity, 'arg1') ``` -------------------------------- ### Execute activity asynchronously example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of executing an activity asynchronously and getting its result. ```ruby future = workflow.execute_activity(MyActivity, 'arg1', 'arg2') result = future.get ``` -------------------------------- ### Client: Starting and Awaiting Workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/README.md Example of using the Temporal client to start a workflow and await its result. ```ruby run_id = Temporal.start_workflow(MyWorkflow, user_id) result = Temporal.await_workflow_result(MyWorkflow, workflow_id: run_id) ``` -------------------------------- ### Starting a Workflow with Input and Options Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Illustrates how to start a workflow with input arguments and specific options like workflow_id. ```ruby Temporal.start_workflow(RenewSubscriptionWorkflow, user_id, options: { workflow_id: user_id }) ``` -------------------------------- ### Clone the repository Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Clone the temporal-ruby repository to get started. ```sh git clone git@github.com:coinbase/temporal-ruby.git ``` -------------------------------- ### Complete Activity Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Example of how to manually complete an activity that was marked as asynchronous. ```ruby Temporal.complete_activity(async_token, 'success') ``` -------------------------------- ### Execute local activity example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of executing an activity locally. ```ruby result = workflow.execute_local_activity(SimpleActivity, data) ``` -------------------------------- ### Signal Workflow Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Example of how to send a signal to a running workflow. ```ruby Temporal.signal_workflow(MyWorkflow, 'pause', 'workflow-123', 'run-123') ``` -------------------------------- ### Continue as new example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of continuing a workflow as new with new data and options. ```ruby workflow.continue_as_new(new_data, options: { workflow_id: existing_id }) ``` -------------------------------- ### Versioning Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example demonstrating how to use `workflow.has_release?` to conditionally execute code based on deployed releases, allowing for gradual rollouts. ```ruby class MyWorkflow < Temporal::Workflow def execute old_activity if !workflow.has_release?(:use_new_activity) new_activity if workflow.has_release?(:use_new_activity) end end ``` -------------------------------- ### Query Workflow Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Example of how to issue a query against a running workflow to retrieve its status. ```ruby status = Temporal.query_workflow(MyWorkflow, 'status', 'workflow-123', 'run-123') ``` -------------------------------- ### Start Worker Processes Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/README.md Starts the three worker processes, each using a different task queue due to differences in payload serialization. ```sh bin/worker USE_ENCRYPTION=1 bin/worker USE_ERROR_SERIALIZATION_V2=1 bin/worker ``` -------------------------------- ### Complete workflow example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of completing a workflow with a result. ```ruby workflow.complete({ status: 'completed' }) ``` -------------------------------- ### Trigger Example Workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/README.md Triggers an example workflow from the 'workflows' directory with optional arguments. ```sh bin/trigger NAME_OF_THE_WORKFLOW [argument_1, argument_2, ...] ``` -------------------------------- ### Configure and start worker process Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Set up and start a worker process to handle workflows and activities. ```ruby require 'path/to/configuration' require 'temporal/worker' worker = Temporal::Worker.new worker.register_workflow(HelloWorldWorkflow) worker.register_activity(HelloActivity) worker.start # runs forever ``` -------------------------------- ### Example Workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md A sample workflow class demonstrating the structure and execution of activities. ```ruby class RenewSubscriptionWorkflow < Temporal::Workflow def execute(user_id) subscription = FetchUserSubscriptionActivity.execute!(user_id) subscription ||= CreateUserSubscriptionActivity.execute!(user_id) return if subscription[:active] ChargeCreditCardActivity.execute!(subscription[:price], subscription[:card_token]) RenewedSubscriptionActivity.execute!(subscription[:id]) SendSubscriptionRenewalEmailActivity.execute!(user_id, subscription[:id]) rescue CreditCardNotChargedError => e CancelSubscriptionActivity.execute!(subscription[:id]) SendSubscriptionCancellationEmailActivity.execute!(user_id, subscription[:id]) end end ``` -------------------------------- ### Defining an Activity Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md An example of how to define a basic activity in Temporal Ruby. ```ruby class CloseUserAccountActivity < Temporal::Activity class UserNotFound < Temporal::ActivityException; end def execute(user_id) user = User.find_by(id: user_id) raise UserNotFound, 'User with specified ID does not exist' unless user user.close_account user.save AccountClosureEmail.deliver(user) return nil end end ``` -------------------------------- ### Get Search Attributes Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of retrieving current search attributes using `workflow.search_attributes`. ```ruby attrs = workflow.search_attributes status = attrs['Status'] ``` -------------------------------- ### Activity Metadata Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity-context.md Get activity execution metadata and log it. ```ruby activity.logger.info("Activity: #{activity.metadata.name} attempt #{activity.metadata.attempt}") ``` -------------------------------- ### Workflow metadata example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of how to access and use workflow metadata. ```ruby workflow.logger.info("Workflow: #{workflow.metadata.name} (#{workflow.metadata.id})") ``` -------------------------------- ### Temporal::Workflow::Future Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/types.md Example of executing an activity and getting its result using Temporal::Workflow::Future. ```ruby future = workflow.execute_activity(MyActivity, arg1) result = future.get # Blocks until activity completes ``` -------------------------------- ### Define an activity Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Example of defining a simple 'HelloActivity' that prints a greeting. ```ruby require 'temporal-ruby' class HelloActivity < Temporal::Activity def execute(name) puts "Hello #{name}!" return nil end end ``` -------------------------------- ### Workflow Breaking Changes Example - Original Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md An example of a workflow before introducing breaking changes. ```ruby class MyWorkflow < Temporal::Workflow def execute ActivityOld1.execute! workflow.sleep(10) ActivityOld2.execute! return nil end end ``` -------------------------------- ### Start a workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Initiate a Temporal workflow execution. ```ruby require 'path/to/configuration' require 'path/to/hello_world_workflow' Temporal.start_workflow(HelloWorldWorkflow) ``` -------------------------------- ### Define a workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Example of defining a 'HelloWorldWorkflow' that executes the 'HelloActivity'. ```ruby require 'path/to/hello_activity' class HelloWorldWorkflow < Temporal::Workflow def execute HelloActivity.execute!('World') return nil end end ``` -------------------------------- ### Query Handler Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of registering a query handler for 'status' within a workflow. ```ruby class MyWorkflow < Temporal::Workflow def execute status = 'running' workflow.on_query('status') do status end # Workflow logic end end # Query from another process: status = Temporal.query_workflow(MyWorkflow, 'status', 'workflow-id', 'run-id') ``` -------------------------------- ### Fail workflow example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of failing a workflow with an exception. ```ruby workflow.fail(StandardError.new('Unexpected error')) ``` -------------------------------- ### Starting a Workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Code snippet for initiating a Temporal workflow execution. ```ruby Temporal.start_workflow(HelloWorldWorkflow) ``` -------------------------------- ### Terminate Workflow Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Example of how to terminate a running workflow with a specified reason. ```ruby Temporal.terminate_workflow('workflow-123', reason: 'User requested cancellation') ``` -------------------------------- ### Complete Example Activity Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity-context.md A comprehensive example of a Temporal Activity demonstrating timeouts, retry policies, heartbeat with progress tracking, and cancellation checks. ```ruby class ProcessDataActivity < Temporal::Activity class DataValidationError < Temporal::ActivityException; end timeouts heartbeat: 30, start_to_close: 3600 retry_policy interval: 1, backoff: 2, max_interval: 60, max_attempts: 3 def execute(data_file_path) # Get heartbeat details from previous retry state = activity.heartbeat_details || { lines_processed: 0 } File.open(data_file_path) do |file| file.each_with_index do |line, index| # Skip already processed lines next if index < state[:lines_processed] # Check for cancellation if activity.cancel_requested raise Temporal::ActivityCanceled, "Processing was cancelled" end # Validate and process unless valid_line?(line) raise DataValidationError, "Invalid line #{index}: #{line}" end process_line(line) # Send heartbeat with progress activity.heartbeat({ lines_processed: index + 1 }) end end return { status: 'completed', lines: state[:lines_processed] } end end ``` -------------------------------- ### Run RSpec Tests Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/README.md Executes the RSpec tests for the Temporal Ruby examples. ```sh bundle exec rspec ``` -------------------------------- ### Temporal.start_workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Start a new workflow execution. ```ruby run_id = Temporal.start_workflow(MyWorkflow, 'arg1', 'arg2', options: { workflow_id: 'unique-id-123', namespace: 'my-namespace', task_queue: 'my-queue' }) ``` -------------------------------- ### Activity Heartbeat Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity.md Example of sending heartbeats within an activity. ```ruby class MyActivity < Temporal::Activity def execute(data) activity.heartbeat('processing step 1') result = process_part_1(data) activity.heartbeat('processing step 2') result = process_part_2(result) return result end end ``` -------------------------------- ### Fetch Workflow Execution Info Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/types.md Example of fetching workflow execution information using the client. ```ruby info = client.fetch_workflow_execution_info(namespace, workflow_id, run_id) ``` -------------------------------- ### Exception Handling Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow.md Example of raising an exception within a workflow to signal failure. ```ruby class MyWorkflow < Temporal::Workflow def execute(user_id) user = FetchUserActivity.execute!(user_id) if user.nil? raise UserNotFound, "User #{user_id} not found" end return user end end ``` -------------------------------- ### Integration Test Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md An example of an integration test file structure that runs against a real Temporal server, contrasting with local testing limitations. ```ruby # integration_spec.rb - runs against real Temporal describe 'Workflow Integration Tests' do # Don't use Testing.local! before do # Register workflows/activities # Point to real Temporal server end it 'tests real async behavior' do # Can test actual retries, timers, async completion, etc. end end ``` -------------------------------- ### Default Signal Handler Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of registering a default signal handler that can handle multiple signal types using a case statement. ```ruby workflow.on_signal do |signal_name, input| case signal_name when 'pause' # Handle pause when 'resume' # Handle resume end end ``` -------------------------------- ### Idempotency Token Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity.md Example of using idempotency tokens to prevent duplicate side effects in activities. ```ruby class CreateUserActivity < Temporal::Activity def execute(email, name) # Unique identifier for this activity execution idempotency_key = activity.workflow_idem # Check if we've already created this user existing = User.find_by(idempotency_key: idempotency_key) return existing if existing # Create new user user = User.create(email: email, name: name, idempotency_key: idempotency_key) return user end end ``` -------------------------------- ### Await Workflow Result Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Example of how to long-poll for a workflow to complete and retrieve its result, with error handling for timeouts. ```ruby begin result = Temporal.await_workflow_result( MyWorkflow, workflow_id: 'my-workflow-123', timeout: 30 ) rescue Temporal::TimeoutError puts "Workflow did not complete within 30 seconds" end ``` -------------------------------- ### Initial retry interval example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example of setting the initial retry interval. ```ruby retry_policy(interval: 1) # First retry waits 1 second ``` -------------------------------- ### Global Configuration Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Demonstrates setting a global host configuration and how it's used by default. ```ruby Temporal.configure do |config| config.host = '127.0.0.1' # sets global host ... end Temporal::Worker.new # uses global host Temporal.start_workflow(...) # uses global host ``` -------------------------------- ### Signal External Workflow Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of sending a signal to another workflow using `workflow.signal_external_workflow`. ```ruby future = workflow.signal_external_workflow( OtherWorkflow, 'notify', 'other-workflow-id', input: { message: 'done' } ) future.wait ``` -------------------------------- ### Named Signal Handler Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of registering a named signal handler for 'pause' within a workflow. ```ruby class MyWorkflow < Temporal::Workflow def execute workflow.on_signal('pause') do |input| # Handle pause signal workflow.logger.info("Paused with input: #{input}") end # Workflow logic end end # Send signal from another process: Temporal.signal_workflow(MyWorkflow, 'pause', 'workflow-id', 'run-id', input) ``` -------------------------------- ### Local Configurations Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Example of setting up multiple clients and workers with explicit local configurations for different Temporal hosts. ```ruby config_1 = Temporal::Configuration.new config_1.host = 'temporal-01' config_2 = Temporal::Configuration.new config_2.host = 'temporal-01' worker_1 = Temporal::Worker.new(config_1) worker_2 = Temporal::Worker.new(config_2) client_1 = Temporal::Client.new(config_1) client_1.start_workflow(...) client_2 = Temporal::Client.new(config_2) client_2.start_workflow(...) ``` -------------------------------- ### Starting Workflow with Inline Retry Policy Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example of overriding the retry policy when starting a workflow. ```ruby run_id = client.start_workflow( MyWorkflow, options: { retry_policy: { interval: 2, backoff: 1.5, max_interval: 120, max_attempts: 10 } } ) ``` -------------------------------- ### UI Execution Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/synchronous-proxy/README.md Starts the user interface process which interacts with the workflow. ```shell ruby ui/main.rb ``` -------------------------------- ### Activity.namespace Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity.md Set or get the activity's namespace. ```ruby class MyActivity < Temporal::Activity namespace 'my-namespace' end ``` -------------------------------- ### Testing Individual Workflows Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md Example of executing a workflow locally for testing purposes. ```ruby require 'temporal/testing' class HelloWorldWorkflow < Temporal::Workflow def execute(name) HelloActivity.execute_locally!(name) end end class HelloActivity < Temporal::Activity def execute(name) "Hello, #{name}!" end end # Test the workflow result = HelloWorldWorkflow.execute_locally('Alice') expect(result).to eq('Hello, Alice!') ``` -------------------------------- ### Complete Activity Asynchronously Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity-context.md Example of completing an activity asynchronously using the async_token. ```ruby Temporal.complete_activity(async_token, { verified: true }) ``` -------------------------------- ### Custom Exceptions in Activities Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity.md Example of defining and throwing custom exceptions in activities. ```ruby class MyActivity < Temporal::Activity class ValidationError < Temporal::ActivityException; end class TemporaryFailure < Temporal::ActivityException; end def execute(data) unless valid?(data) raise ValidationError, "Data validation failed: #{data}" end begin process(data) rescue TimeoutError => e raise TemporaryFailure, "Timeout processing #{data}: #{e.message}" end end end ``` -------------------------------- ### Worker Execution Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/synchronous-proxy/README.md Starts the Temporal worker process. ```shell ruby worker/worker.rb ``` -------------------------------- ### Activity.headers Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity.md Set or get custom headers for the activity. ```ruby class MyActivity < Temporal::Activity headers 'x-custom-header' => 'value' end ``` -------------------------------- ### Temporal::Workflow::ChildWorkflowFuture Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/types.md Example of executing a child workflow and getting its result using Temporal::Workflow::ChildWorkflowFuture. ```ruby future = workflow.execute_workflow(ChildWorkflow, arg) result = future.get ``` -------------------------------- ### Worker initialization options Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Demonstrates various options that can be passed when initializing a Temporal worker. ```ruby Temporal::Worker.new( activity_thread_pool_size: 20, # how many threads poll for activities workflow_thread_pool_size: 10, # how many threads poll for workflows binary_checksum: nil, # identifies the version of workflow worker code activity_poll_retry_seconds: 0, # how many seconds to wait after unsuccessful poll for activities workflow_poll_retry_seconds: 0, # how many seconds to wait after unsuccessful poll for workflows activity_max_tasks_per_second: 0 # rate-limit for starting activity tasks (new activities + retries) on the task queue ) ``` -------------------------------- ### Install Temporal dependencies using Docker Compose Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Instructions to set up a local Temporal service using Docker Compose. ```sh curl -O https://raw.githubusercontent.com/temporalio/docker-compose/main/docker-compose.yml docker-compose up ``` -------------------------------- ### Fail Activity Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Manually fail an activity that was marked as async. ```ruby Temporal.fail_activity(async_token, MyError.new('Failed')) ``` -------------------------------- ### Execute Child Workflow Synchronously Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of executing a child workflow synchronously (blocking) and getting its result. ```ruby result = workflow.execute_workflow!(ChildWorkflow, 'arg1') ``` -------------------------------- ### Workflow Current Time Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example demonstrating the usage of `workflow.now` to get the current time within the workflow context. ```ruby start_time = workflow.now workflow.sleep(60) end_time = workflow.now # 60 seconds later (approximately) ``` -------------------------------- ### Temporal::Schedule::Schedule Constructor Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/types.md Example of creating a new schedule definition. ```ruby schedule = Temporal::Schedule::Schedule.new( spec: schedule_spec, action: action, policies: policies, state: state ) ``` -------------------------------- ### Handling Workflow Execution Already Started Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Provides an example of catching `Temporal::WorkflowExecutionAlreadyStartedFailure` and accessing the existing run ID. ```ruby begin client.start_workflow(MyWorkflow, options: { workflow_id: 'unique-id' }) client.start_workflow(MyWorkflow, options: { workflow_id: 'unique-id' }) # Raises! rescue Temporal::WorkflowExecutionAlreadyStartedFailure => e puts "Workflow already started with run_id: #{e.run_id}" end ``` -------------------------------- ### Composite Converter Configuration Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/configuration.md Example of configuring a composite converter with various payload converters. ```ruby config.converter = Temporal::Connection::Converter::Composite.new( payload_converters: [ Temporal::Connection::Converter::Payload::Nil.new, Temporal::Connection::Converter::Payload::Bytes.new, Temporal::Connection::Converter::Payload::ProtoJSON.new, Temporal::Connection::Converter::Payload::JSON.new ] ) ``` -------------------------------- ### Idempotency Token for Workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity-context.md Example of using `activity.workflow_idem` to get a unique identifier for an activity across all executions of the workflow, ensuring idempotency across runs and retries. ```ruby class IncrementCounterActivity < Temporal::Activity def execute(counter_id) idempotency_key = activity.workflow_idem # Only increment once, even if workflow is replayed Counter.increment_once(counter_id, idempotency_key) end end ``` -------------------------------- ### Idempotency Token for Activity Run Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity-context.md Example of using `activity.run_idem` to get a unique identifier for an activity execution within the current workflow run, ensuring idempotency. ```ruby class CreateRecordActivity < Temporal::Activity def execute(data) idempotency_key = activity.run_idem existing = Record.find_by(idempotency_key: idempotency_key) return existing if existing record = Record.create(data.merge(idempotency_key: idempotency_key)) return record end end ``` -------------------------------- ### Combining Credentials Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Example of configuring both SSL and OAuth2 token credentials using the `compose` method. ```ruby Temporal.configure do |config| config.host = 'localhost' config.port = 7233 config.namespace = 'ruby-samples' config.task_queue = 'hello-world' config.credentials = GRPC::Core::ChannelCredentials.new(root_cert, client_key, client_chain).compose( GRPC::Core::CallCredentials.new(token.updater_proc) ) end ``` -------------------------------- ### Register Namespace and Search Attributes Source: https://github.com/coinbase/temporal-ruby/blob/master/examples/README.md Runs a script to ensure the 'ruby-samples' namespace and necessary search attributes are created. ```sh bin/register_namespace ``` -------------------------------- ### Executing Activities from Workflow Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Demonstrates different ways to execute activities from within a workflow, including blocking, non-blocking, and by name. ```ruby # Calls the activity by its class and blocks the execution until activity is # finished. The return value of your activity will get assigned to the result result = MyActivity.execute!(arg1, arg2) # Here's a non-blocking version of the execute, returning back the future that # will get fulfilled when activity completes. This approach allows modelling # asynchronous workflows with activities executed in parallel future = MyActivity.execute(arg1, arg2) result = future.get # Full versions of the calls from above, but has more flexibility (shown below) result = workflow.execute_activity!(MyActivity, arg1, arg2) future = workflow.execute_activity(MyActivity, arg1, arg2) # In case your workflow code does not have access to activity classes (separate # process, activities implemented in a different language, etc), you can # simply reference them by their names workflow.execute_activity('MyActivity', arg1, arg2, options: { namespace: 'my-namespace', task_queue: 'my-task-queue' }) ``` -------------------------------- ### Multiple Clients with Different Configurations Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/configuration.md Demonstrates how to create and use multiple Temporal clients with distinct configurations. ```ruby config1 = Temporal::Configuration.new config1.host = 'temporal-1.example.com' config1.namespace = 'namespace1' config2 = Temporal::Configuration.new config2.host = 'temporal-2.example.com' config2.namespace = 'namespace2' client1 = Temporal::Client.new(config1) client2 = Temporal::Client.new(config2) client1.start_workflow(Workflow1) client2.start_workflow(Workflow2) ``` -------------------------------- ### CancellableActivity Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Example of an activity that can be canceled during execution. ```ruby class CancellableActivity < Temporal::Activity def execute(items) items.each do |item| activity.heartbeat if activity.cancel_requested raise Temporal::ActivityCanceled, 'Operation cancelled' end process(item) end end end ``` -------------------------------- ### Temporal::Client.new(config) Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/client.md Create a new client instance with explicit configuration. ```ruby config = Temporal::Configuration.new config.host = 'localhost' config.port = 7233 config.namespace = 'my-namespace' client = Temporal::Client.new(config) client.start_workflow(MyWorkflow) ``` -------------------------------- ### Temporal::Configuration.new Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/configuration.md Create a new configuration instance with defaults. ```ruby config = Temporal::Configuration.new config.host = 'localhost' config.port = 7233 config.namespace = 'my-namespace' ``` -------------------------------- ### Validation example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example of validating retry policy configuration. ```ruby policy = Temporal::RetryPolicy.new( interval: 1, backoff: 2, max_interval: 60, max_attempts: 5 ) policy.validate! # Passes policy = Temporal::RetryPolicy.new(max_attempts: 3) # Missing interval/backoff policy.validate! # Raises InvalidRetryPolicy ``` -------------------------------- ### WorkflowTerminated Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Example demonstrating how to catch Temporal::WorkflowTerminated. ```ruby begin result = client.await_workflow_result(MyWorkflow, workflow_id: 'wf-123') rescue Temporal::WorkflowTerminated puts "Workflow was terminated" end ``` -------------------------------- ### With Custom Logger and Metrics Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/configuration.md Shows how to configure a custom logger and a metrics adapter. ```ruby Temporal.configure do |config| config.logger = Logger.new('temporal.log', 'daily') config.logger.level = Logger::INFO config.metrics_adapter = Prometheus::MetricsAdapter.new end ``` -------------------------------- ### Non-retriable errors example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example of specifying errors that should not trigger a retry. ```ruby retry_policy( interval: 1, backoff: 2, max_attempts: 5, non_retriable_errors: [ 'ValidationError', 'AuthenticationError', 'InvalidInputError' ] ) class MyActivity < Temporal::Activity # Raises ValidationError - will NOT be retried # Raises TimeoutError - WILL be retried end ``` -------------------------------- ### Max attempts example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example of configuring the maximum number of attempts. ```ruby retry_policy(interval: 1, backoff: 2, max_interval: 60, max_attempts: 5) # Initial attempt + 4 retries = 5 total attempts max ``` -------------------------------- ### Workflow with Signals and Queries Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md Illustrates a workflow that handles signals and queries, demonstrating how to manage workflow state and respond to external events during testing. ```ruby require 'temporal/testing' class InterruptibleWorkflow < Temporal::Workflow def execute(items) @status = 'processing' @items_processed = 0 workflow.on_query('status') do { status: @status, processed: @items_processed } end workflow.on_signal('cancel') do @status = 'cancelled' end items.each do |item| break if @status == 'cancelled' process_item(item) @items_processed += 1 end @status end private def process_item(item) # Process item end end # Tests RSpec.describe InterruptibleWorkflow do it 'processes all items without interruption' do result = InterruptibleWorkflow.execute_locally(%w[1 2 3]) expect(result).to eq('processing') end end ``` -------------------------------- ### Exponential backoff example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example demonstrating exponential backoff behavior. ```ruby # interval: 1, backoff: 2 # Retry 1: wait 1 second # Retry 2: wait 2 seconds (1 * 2) # Retry 3: wait 4 seconds (2 * 2) # Retry 4: wait 8 seconds (4 * 2) # ... capped by max_interval ``` -------------------------------- ### External Completion Activity Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity-context.md Demonstrates how to use `activity.async_token` to send a token to an external system for later activity completion. ```ruby class ExternalCompletionActivity < Temporal::Activity def execute(request_id) token = activity.async_token # Send to external system ExternalService.submit_request(request_id, callback_url: "http://localhost:3000/complete?token=#{token}") activity.async end end # In your HTTP handler: post '/complete' do token = params[:token] result = { status: 'completed' } Temporal.complete_activity(token, result) 'OK' end ``` -------------------------------- ### ExecutionOptions Construction Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/types.md Shows how to construct Temporal::ExecutionOptions with workflow class and configuration. ```ruby options = Temporal::ExecutionOptions.new( workflow_class, { namespace: 'custom', task_queue: 'custom-queue' }, defaults ) ``` -------------------------------- ### Maximum interval example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/retry-policy.md Example showing how max_interval caps the retry duration. ```ruby # interval: 1, backoff: 2, max_interval: 60 # Retry 1: wait 1 second # Retry 2: wait 2 seconds # Retry 3: wait 4 seconds # Retry 4: wait 8 seconds # Retry 5: wait 16 seconds # Retry 6: wait 32 seconds # Retry 7: wait 60 seconds (capped) # Retry 8: wait 60 seconds (capped) ``` -------------------------------- ### Asynchronous Activity Completion Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Demonstrates how to handle asynchronous operations within an activity by manually completing it later. ```ruby class AsyncActivity < Temporal::Activity def execute(user_id) user = User.find_by(id: user_id) # Pass the async_token to complete your activity later ExternalSystem.verify_user(user, activity.async_token) activity.async # prevents activity from completing immediately end end ``` -------------------------------- ### Upsert Search Attributes Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of updating or adding search attributes using `workflow.upsert_search_attributes`. ```ruby workflow.upsert_search_attributes({ 'Status' => 'processing', 'Priority' => 'high' }) ``` -------------------------------- ### Manual Activity Completion and Failure Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Shows how to manually complete or fail an asynchronous activity using a token. ```ruby Temporal.complete_activity(async_token, result) ``` ```ruby Temporal.fail_activity(async_token, MyError.new('Something went wrong')) ``` -------------------------------- ### Global Configuration Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/README.md Example of configuring the Temporal client globally using Temporal.configure. ```ruby Temporal.configure do |config| config.host = 'localhost' config.port = 7233 config.namespace = 'default' config.task_queue = 'my-queue' config.timeouts = { execution: 3600, task: 10, start_to_close: 300 } end ``` -------------------------------- ### Workflow Breaking Changes Example - Updated Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md An updated workflow demonstrating how to handle breaking changes using workflow.has_release?. ```ruby class MyWorkflow < Temporal::Workflow def execute Activity1.execute! if workflow.has_release?(:fix_1) ActivityNew1.execute! end workflow.sleep(10) if workflow.has_release?(:fix_1) ActivityNew2.execute! else ActivityOld.execute! end if workflow.has_release?(:fix_2) ActivityNew3.execute! end return nil end end ``` -------------------------------- ### WorkflowTimedOut Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Example demonstrating how to catch Temporal::WorkflowTimedOut and distinguish it from Temporal::TimeoutError. ```ruby begin result = client.await_workflow_result(MyWorkflow, workflow_id: 'wf-123') rescue Temporal::WorkflowTimedOut puts "Workflow timed out" rescue Temporal::TimeoutError puts "Polling for result timed out" end ``` -------------------------------- ### Worker Initialization Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/worker.md Create a new worker instance with specified thread pool sizes and binary checksum. ```ruby worker = Temporal::Worker.new( activity_thread_pool_size: 10, workflow_thread_pool_size: 5, binary_checksum: 'v1.0.0' ) ``` -------------------------------- ### ActivityNotRegistered Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Example demonstrating how Temporal::ActivityNotRegistered is raised when an activity is not registered with the worker. ```ruby worker = Temporal::Worker.new worker.register_activity(RegisteredActivity) # Forgot to register UnregisteredActivity # This raises ActivityNotRegistered: class MyWorkflow < Temporal::Workflow def execute UnregisteredActivity.execute!('arg') # Raises! end end ``` -------------------------------- ### Integration Testing with Local Mode Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md Demonstrates how to use `Temporal::Testing.local!` to run integration tests against a local Temporal instance, simulating a real server environment. ```ruby require 'temporal/testing' require 'temporal/worker' RSpec.describe 'Workflow Integration' do before(:each) do Temporal::Testing.local! end it 'processes complete workflow chain' do # Configure Temporal Temporal.configure do |config| config.namespace = 'test' config.task_queue = 'test-queue' end # Start workflows using normal client API run_id = Temporal.start_workflow(MyWorkflow, 'test-data') # Get result (executes immediately in local mode) result = Temporal.await_workflow_result(MyWorkflow, workflow_id: run_id) expect(result).to be_success end end ``` -------------------------------- ### Side Effect Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/workflow-context.md Example of using `workflow.side_effect` to execute a non-deterministic block whose result is recorded for replay. ```ruby random_value = workflow.side_effect { rand(0..100) } ``` -------------------------------- ### Middleware Call Method Example Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Defines a middleware class with a 'call' method that executes code before and after yielding to the next middleware or the target method. ```ruby class MyMiddleware def call(metadata) puts "Before execution" yield puts "After execution" result end end ``` -------------------------------- ### Start Worker Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/worker.md Starts the worker, which blocks indefinitely, polling for tasks and executing them. Handles SIGTERM and SIGINT for graceful shutdown. ```ruby worker = Temporal::Worker.new worker.register_workflow(MyWorkflow) worker.register_activity(MyActivity) worker.start # Runs forever until interrupted ``` -------------------------------- ### InvalidRetryPolicy Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Example demonstrating an invalid retry policy configuration that would raise Temporal::InvalidRetryPolicy. ```ruby policy = Temporal::RetryPolicy.new( interval: 0, # Invalid: must be > 0 backoff: 2, max_attempts: 5 ) policy.validate! # Raises InvalidRetryPolicy ``` -------------------------------- ### Unit Test Workflows Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md Demonstrates how to unit test workflow logic by mocking activities and using `execute_locally`. ```ruby class MyWorkflow < Temporal::Workflow def execute(user_id) user = FetchUserActivity.execute!(user_id) return user if user.premium? upgrade_result = UpgradeActivity.execute!(user_id) return upgrade_result end end # Unit test RSpec.describe MyWorkflow do it 'skips upgrade for premium users' do allow_any_instance_of(FetchUserActivity) .to receive(:execute) .and_return({ premium: true }) expect_any_instance_of(UpgradeActivity).not_to receive(:execute) result = MyWorkflow.execute_locally('user-123') expect(result[:premium]).to be true end end ``` -------------------------------- ### Workflow with Timers Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md Demonstrates a workflow that uses a timer and an activity, showing how to handle timeouts in local testing. ```ruby require 'temporal/testing' class TimeoutWorkflow < Temporal::Workflow def execute(data, timeout_seconds) timer = workflow.start_timer(timeout_seconds) activity_future = workflow.execute_activity(SlowActivity, data) workflow.wait_for_any(timer, activity_future) if timer.finished? return { status: 'timeout' } else return activity_future.get end end end class SlowActivity < Temporal::Activity def execute(data) { status: 'completed', data: data } end end # Tests RSpec.describe TimeoutWorkflow do it 'returns activity result when activity completes first' do result = TimeoutWorkflow.execute_locally('data', 60) expect(result[:status]).to eq('completed') end it 'returns timeout when timer fires first' do # In local testing, timers fire immediately # You'd need to mock the timer behavior result = TimeoutWorkflow.execute_locally('data', 0) expect(result[:status]).to eq('timeout') end end ``` -------------------------------- ### Configure Temporal connection and register namespace Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Configure the Temporal connection details (host, port, namespace, task queue) and register a new namespace. ```ruby require 'temporal-ruby' Temporal.configure do |config| config.host = 'localhost' config.port = 7233 config.namespace = 'ruby-samples' config.task_queue = 'hello-world' config.credentials = :this_channel_is_insecure end begin Temporal.register_namespace('ruby-samples', 'A safe space for playing with Temporal Ruby') rescue Temporal::NamespaceAlreadyExistsFailure nil # service was already registered end ``` -------------------------------- ### SecondDynamicActivityError Example Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Example showing the error raised when attempting to register a second dynamic activity for the same task queue. ```ruby worker.register_dynamic_activity(DynamicActivity1) worker.register_dynamic_activity(DynamicActivity2) # Raises! ``` -------------------------------- ### Handling Workflow Start Errors Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/errors.md Demonstrates how to catch `Temporal::WorkflowExecutionAlreadyStartedFailure` when trying to start a workflow that is already running. ```ruby begin run_id = client.start_workflow( MyWorkflow, options: { workflow_id: 'unique-id' } ) rescue Temporal::WorkflowExecutionAlreadyStartedFailure => e puts "Workflow already running with run_id: #{e.run_id}" # Retry with different ID or use workflow_id_reuse_policy end ``` -------------------------------- ### Basic Configuration Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/configuration.md Basic configuration for connecting to a Temporal server. ```ruby Temporal.configure do |config| config.host = 'localhost' config.port = 7233 config.namespace = 'default' config.task_queue = 'my-queue' end ``` -------------------------------- ### Testing in Local Mode - Usage within a block Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/testing.md This example demonstrates how to enable and disable local mode for a specific block of code. ```ruby # All workflows in this block execute locally Temporal::Testing.local! do run_id = Temporal.start_workflow(MyWorkflow, 'arg') # Workflow executes immediately end # Back to normal mode result = Temporal.start_workflow(AnotherWorkflow) # Returns run_id, doesn't execute ``` -------------------------------- ### Periodic Workflow Execution Example Source: https://github.com/coinbase/temporal-ruby/blob/master/README.md Schedules a workflow to run periodically using a cron schedule. ```ruby Temporal.schedule_workflow(HealthCheckWorkflow, '*/5 * * * *') ``` -------------------------------- ### Temporal.configure Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/temporal-module.md Configure the global Temporal client with connection settings, timeouts, and execution defaults. ```ruby Temporal.configure do |config| config.host = '127.0.0.1' config.port = 7233 config.namespace = 'default' config.task_queue = 'my-queue' config.credentials = :this_channel_is_insecure end ``` ```ruby Temporal.configure do |config| config.host = 'localhost' config.port = 7233 config.namespace = 'ruby-samples' config.task_queue = 'hello-world' end ``` -------------------------------- ### Activity.timeouts Source: https://github.com/coinbase/temporal-ruby/blob/master/_autodocs/api-reference/activity.md Set or get the activity's timeouts. ```ruby class MyActivity < Temporal::Activity timeouts schedule_to_close: 3600, start_to_close: 300, heartbeat: 60 end ```