with Temporal.io
Michał Samluk
Principal Engineer, Architect @ MAXIO
How our components should interact?
Async + orchestrator
Durable Execution Platform
Our choice: Temporal.io
Works on both stacks Ruby & Python
https://github.com/coinbase/temporal-ruby
class MyWorkflow < Temporal::Workflow
def execute
# Here you will execute your activities
end
end
Temporal.start_workflow(MyWorkflow)
class HelloWorldActivity < Temporal::Activity
def execute(name)
text = "Hello World, #{name}"
puts text
return text
end
end
class RenewSubscriptionWorkflow < Temporal::Workflow
def execute(user_id)
subscription = FetchUserSubscriptionActivity.execute!(user_id)
subscription ||= CreateUserSubscriptionActivity.execute!(user_id)
ChargeCreditCardActivity.execute!(subscription[:price], subscription[:card_token])
RenewedSubscriptionActivity.execute!(subscription[:id])
SendSubscriptionRenewalEmailActivity.execute!(user_id, subscription[:id])
end
end
class RenewSubscriptionWorkflow < Temporal::Workflow
def execute(user_id)
subscription = FetchUserSubscriptionActivity.execute!(user_id)
subscription ||= CreateUserSubscriptionActivity.execute!(user_id)
ChargeCreditCardActivity.execute!(subscription[:price], subscription[:card_token])
# ...
rescue CreditCardNotChargedError => e
CancelSubscriptionActivity.execute!(subscription[:id])
SendSubscriptionCancellationEmailActivity.execute!(user_id, subscription[:id])
end
end
class RetryableActivity < Temporal::Activity
retry_policy(
interval: 1,
backoff: 1,
max_attempts: 3,
non_retriable_errors: [NonRetriableError]
)
def execute(user_id)
# ...
end
end
Event Sourcing
Allows to build custom propagators
Scales horizontaly workers
Seperate workers for activity and workflow tasks