Last Updated : 2026-01-08
Status : Active
<- Back to Worker Crates Overview
This document provides a quick reference for the aligned APIs across Ruby, Python, TypeScript, and Rust worker implementations. All four languages share consistent patterns for handler execution, result creation, registry operations, and composition via mixins/traits.
Language Base Class Signature
Ruby TaskerCore::StepHandler::Basedef call(context)
Python BaseStepHandlerdef call(self, context: StepContext) -> StepHandlerResult
TypeScript StepHandlerasync call(context: StepContext): Promise<StepHandlerResult>
Rust StepHandler traitasync fn call(&self, step_data: &TaskSequenceStep) -> StepExecutionResult
All languages use composition via mixins/traits rather than inheritance hierarchies.
Language Base Mixin Syntax Example
Ruby StepHandler::Baseinclude Mixins::APIclass Handler < Base; include Mixins::API
Python StepHandlerMultiple inheritance class Handler(StepHandler, APIMixin)
TypeScript StepHandlerapplyAPI(this)Mixin functions applied in constructor
Rust impl StepHandlerimpl APICapableMultiple trait implementations
Capability Ruby Python TypeScript Rust
API Mixins::APIAPIMixinapplyAPI()APICapable
Decision Mixins::DecisionDecisionMixinapplyDecision()DecisionCapable
Batchable Mixins::BatchableBatchableMixinBatchableHandlerBatchableCapable
The StepContext provides unified access to step execution data across Ruby, Python, and TypeScript.
Field Type Description
task_uuidString Unique task identifier (UUID v7)
step_uuidString Unique step identifier (UUID v7)
input_dataDict/Hash Input data for the step from workflow_step.inputs
step_inputsDict/Hash Alias for input_data
step_configDict/Hash Handler configuration from step_definition.handler.initialization
dependency_resultsWrapper Results from parent steps (DependencyResultsWrapper)
retry_countInteger Current retry attempt (from workflow_step.attempts)
max_retriesInteger Maximum retry attempts (from workflow_step.max_attempts)
Method Description
get_task_field(name)Get field from task context
get_dependency_result(step_name)Get result from a parent step
Property Type Description
taskTaskWrapper Full task wrapper with context and metadata
workflow_stepWorkflowStepWrapper Workflow step with execution state
step_definitionStepDefinitionWrapper Step definition from task template
Language Method Example
Ruby success(result:, metadata:)success(result: { id: 123 }, metadata: { ms: 50 })
Python self.success(result, metadata)self.success({"id": 123}, {"ms": 50})
Rust StepExecutionResult::success(...)StepExecutionResult::success(result, metadata)
Language Method Key Parameters
Ruby failure(message:, error_type:, error_code:, retryable:, metadata:)keyword arguments
Python self.failure(message, error_type, error_code, retryable, metadata)positional/keyword
Rust StepExecutionResult::failure(...)structured fields
Field Ruby Python Rust Description
success bool bool bool Whether step succeeded
result Hash Dict HashMap Result data
metadata Hash Dict HashMap Additional context
error_message String str String Human-readable error
error_type String str String Error classification
error_code String (optional) str (optional) String (optional) Application error code
retryable bool bool bool Whether to retry
Use these standard values for consistent error classification:
Value Description Retry Behavior
PermanentErrorNon-recoverable failure Never retry
RetryableErrorTemporary failure Will retry
ValidationErrorInput validation failed No retry
TimeoutErrorOperation timed out May retry
UnexpectedErrorUnexpected handler error May retry
Operation Ruby Python Rust
Register register(name, klass)register(name, klass)register_handler(name, handler)
Check is_registered(name)is_registered(name)is_registered(name)
Resolve resolve(name)resolve(name)get_handler(name)
List list_handlerslist_handlers()list_handlers()
Note : Ruby also provides original method names (register_handler, handler_available?, resolve_handler, registered_handlers) as the primary API with the above as cross-language aliases.
Handler resolution uses a chain-of-responsibility pattern to convert callable addresses into executable handlers.
Method Ruby Python TypeScript Rust
Get Name nameresolver_name()resolverName()resolver_name(&self)
Get Priority prioritypriority()priority()priority(&self)
Can Resolve? can_resolve?(definition, config)can_resolve(definition)canResolve(definition)can_resolve(&self, definition)
Resolve resolve(definition, config)resolve(definition, context)resolve(definition, context)resolve(&self, definition, context)
Operation Ruby Python TypeScript Rust
Create ResolverChain.newResolverChain()new ResolverChain()ResolverChain::new()
Register register(resolver)register(resolver)register(resolver)register(resolver)
Resolve resolve(definition, context)resolve(definition, context)resolve(definition, context)resolve(definition, context)
Can Resolve? can_resolve?(definition)can_resolve(definition)canResolve(definition)can_resolve(definition)
List resolversresolversresolversresolvers()
Resolver Priority Function Rust Ruby Python TypeScript
ExplicitMappingResolver 10 Hash lookup of registered handlers ✅ ✅ ✅ ✅
ClassConstantResolver 100 Runtime class lookup (Ruby) ❌ ✅ - -
ClassLookupResolver 100 Runtime class lookup (Python/TS) ❌ - ✅ ✅
Note : Class lookup resolvers are not available in Rust due to lack of runtime reflection. Rust handlers must use ExplicitMappingResolver. Ruby uses ClassConstantResolver (Ruby terminology); Python and TypeScript use ClassLookupResolver (same functionality, language-appropriate naming).
Field Type Description Required
callableString Handler address (name or class path) Yes
methodString Entry point method (default: "call") No
resolverString Resolution hint to bypass chain No
initializationDict/Hash Handler configuration No
Multi-method handlers expose multiple entry points through the method field:
Language Default Method Dynamic Dispatch
Ruby callhandler.public_send(method, context)
Python callgetattr(handler, method)(context)
TypeScript callhandler[method](context)
Rust callhandler.invoke_method(method, step)
Creating Multi-Method Handlers:
Language Signature
Ruby Define additional methods alongside call
Python Define additional methods alongside call
TypeScript Define additional async methods alongside call
Rust Implement invoke_method to dispatch to internal methods
See Handler Resolution Guide for complete documentation.
Operation Ruby Python TypeScript
GET get(path, params: {}, headers: {})self.get(path, params={}, headers={})this.get(path, params?, headers?)
POST post(path, data: {}, headers: {})self.post(path, data={}, headers={})this.post(path, data?, headers?)
PUT put(path, data: {}, headers: {})self.put(path, data={}, headers={})this.put(path, data?, headers?)
DELETE delete(path, params: {}, headers: {})self.delete(path, params={}, headers={})this.delete(path, params?, headers?)
Language Simple API Result Fields
Ruby decision_success(steps:, routing_context:)decision_point_outcome: { type, step_names }
Python decision_success(steps, routing_context)decision_point_outcome: { type, step_names }
TypeScript decisionSuccess(steps, routingContext?)decision_point_outcome: { type, step_names }
Rust decision_success(step_uuid, step_names, ...)Pattern-based
Decision Helper Methods (Cross-Language):
decision_success(steps, routing_context) - Create dynamic steps
skip_branches(reason, routing_context) - Skip all conditional branches
decision_failure(message, error_type) - Decision could not be made
Operation Ruby Python TypeScript
Get Context get_batch_context(context)get_batch_context(context)getBatchContext(context)
Complete Batch batch_worker_complete(processed_count:, result_data:)batch_worker_complete(processed_count, result_data)batchWorkerComplete(processedCount, resultData)
Handle No-Op handle_no_op_worker(batch_ctx)handle_no_op_worker(batch_ctx)handleNoOpWorker(batchCtx)
Standard Batch Result Fields:
processed_count / items_processed
items_succeeded / items_failed
start_cursor, end_cursor, batch_size, last_cursor
Cursor Indexing:
All languages use 0-indexed cursors (start at 0, not 1)
Ruby was updated from 1-indexed to 0-indexed for consistency
Checkpoint yielding enables batch workers to persist progress and yield control for re-dispatch.
Operation Ruby Python TypeScript
Checkpoint checkpoint_yield(cursor:, items_processed:, accumulated_results:)checkpoint_yield(cursor, items_processed, accumulated_results)checkpointYield({ cursor, itemsProcessed, accumulatedResults })
BatchWorkerContext Checkpoint Accessors:
Accessor Ruby Python TypeScript
Cursor checkpoint_cursorcheckpoint_cursorcheckpointCursor
Accumulated Results accumulated_resultsaccumulated_resultsaccumulatedResults
Has Checkpoint? has_checkpoint?has_checkpoint()hasCheckpoint()
Items Processed checkpoint_items_processedcheckpoint_items_processedcheckpointItemsProcessed
FFI Contract:
Function Description
checkpoint_yield_step_event(event_id, data)Persist checkpoint and re-dispatch step
Key Invariants:
Progress is atomically saved before re-dispatch
Step remains InProgress during checkpoint yield cycle
Only Success/Failure trigger state transitions
See Batch Processing Guide - Checkpoint Yielding for full documentation.
Language Base Class Key Method
Ruby TaskerCore::DomainEvents::BasePublisherpublish(ctx)
Python BasePublisherpublish(ctx)
TypeScript BasePublisherpublish(ctx)
Rust StepEventPublisher traitpublish(ctx)
All languages support publisher lifecycle hooks for instrumentation:
Hook Ruby Python TypeScript Description
Before Publish before_publish(ctx)before_publish(ctx)beforePublish(ctx)Called before publishing
After Publish after_publish(ctx, result)after_publish(ctx, result)afterPublish(ctx, result)Called after successful publish
On Error on_publish_error(ctx, error)on_publish_error(ctx, error)onPublishError(ctx, error)Called on publish failure
Metadata additional_metadata(ctx)additional_metadata(ctx)additionalMetadata(ctx)Inject custom metadata
Field Description
task_uuidTask identifier
step_uuidStep identifier
step_nameHandler/step name
namespaceTask namespace
correlation_idTracing correlation ID
resultStep execution result
metadataAdditional metadata
Language Base Class Key Methods
Ruby TaskerCore::DomainEvents::BaseSubscribersubscribes_to, handle(event)
Python BaseSubscribersubscribes_to(), handle(event)
TypeScript BaseSubscribersubscribesTo(), handle(event)
Rust EventHandler closures N/A
All languages support subscriber lifecycle hooks:
Hook Ruby Python TypeScript Description
Before Handle before_handle(event)before_handle(event)beforeHandle(event)Called before handling
After Handle after_handle(event, result)after_handle(event, result)afterHandle(event, result)Called after handling
On Error on_handle_error(event, error)on_handle_error(event, error)onHandleError(event, error)Called on handler failure
Language Publisher Registry Subscriber Registry
Ruby PublisherRegistry.instanceSubscriberRegistry.instance
Python PublisherRegistry.instance()SubscriberRegistry.instance()
TypeScript PublisherRegistry.getInstance()SubscriberRegistry.getInstance()
Before After
def call(task, sequence, step)def call(context)
class Handler < APIclass Handler < Base; include Mixins::API
task.context['field']context.get_task_field('field')
sequence.get_results('step')context.get_dependency_result('step')
1-indexed cursors 0-indexed cursors
Before After
def handle(self, task, sequence, step)def call(self, context)
class Handler(APIHandler)class Handler(StepHandler, APIMixin)
N/A self.success(result, metadata)
N/A Publisher/Subscriber lifecycle hooks
Before After
class Handler extends APIHandlerclass Handler extends StepHandler implements APICapable
No domain events Complete domain events module
N/A Publisher/Subscriber lifecycle hooks
N/A applyAPI(this), applyDecision(this) mixins
Before After
(already aligned) (already aligned)
N/A APICapable, DecisionCapable, BatchableCapable traits