Skip to content

Commit e49257e

Browse files
committed
Simple activity, context propagation, and message passing samples
1 parent 45502eb commit e49257e

26 files changed

Lines changed: 808 additions & 10 deletions

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ jobs:
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
os: [ubuntu-latest, macos-12, macos-latest]
14+
os: [ubuntu-latest, macos-13, macos-latest]
1515
# Earliest and latest supported
16-
rubyVersion: ["3.1", "3.3"]
16+
rubyVersion: ["3.2", "3.4"]
1717
runs-on: ${{ matrix.os }}
1818
steps:
1919
- name: Checkout repository

.rubocop.yml

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,46 @@
11
AllCops:
22
NewCops: enable
3-
TargetRubyVersion: 3.1
4-
SuggestExtensions: false
3+
TargetRubyVersion: 3.2
4+
SuggestExtensions: false
5+
6+
# Don't need super for activities or workflows
7+
Lint/MissingSuper:
8+
AllowedParentClasses:
9+
- Temporalio::Activity::Definition
10+
- Temporalio::Workflow::Definition
11+
12+
# The default is too small and triggers simply setting lots of values on a proto
13+
Metrics/AbcSize:
14+
Max: 200
15+
16+
# The default is too small
17+
Metrics/BlockLength:
18+
Max: 100
19+
20+
# The default is too small
21+
Metrics/ClassLength:
22+
Max: 1000
23+
24+
# The default is too small
25+
Metrics/CyclomaticComplexity:
26+
Max: 100
27+
28+
# The default is too small
29+
Metrics/MethodLength:
30+
Max: 100
31+
32+
# The default is too small
33+
Metrics/ModuleLength:
34+
Max: 1000
35+
36+
# The default is too small
37+
Metrics/PerceivedComplexity:
38+
Max: 40
39+
40+
# Don't need API docs for samples
41+
Style/Documentation:
42+
Enabled: false
43+
44+
# Don't need API docs for samples
45+
Style/DocumentationMethod:
46+
Enabled: false

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
source 'https://rubygems.org'
44

5-
gem 'temporalio'
5+
gem 'temporalio', path: '../temporal-sdk-ruby/temporalio'
66

77
group :development do
88
gem 'minitest'

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,19 @@ until the SDK is marked stable.
1111

1212
Prerequisites:
1313

14-
* Ruby 3.1+
14+
* Ruby 3.2+
1515
* Local Temporal server running (can [install CLI](https://docs.temporal.io/cli#install) then
1616
[run a dev server](https://docs.temporal.io/cli#start-dev-server))
1717
* `bundle install` run in the root
1818

1919
## Samples
2020

2121
<!-- Keep this list in alphabetical order -->
22+
* [activity_simple](activity_simple) - Simple workflow that calls two activities.
2223
* [activity_worker](activity_worker) - Use Ruby activities from a workflow in another language.
24+
* [context_propagation](context_propagation) - Use interceptors to propagate thread/fiber local data from clients
25+
through workflows/activities.
26+
* [message_passing_simple](message_passing_simple) - Simple workflow that accepts signals, queries, and updates.
2327

2428
## Development
2529

activity_simple/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Activity Simple
2+
3+
This sample shows calling a couple of simple activities from a simple workflow.
4+
5+
To run, first see [README.md](../README.md) for prerequisites. Then, in another terminal, start the Ruby worker
6+
from this directory:
7+
8+
bundle exec ruby worker.rb
9+
10+
Finally in another terminal, use the Ruby client to the workflow from this directory:
11+
12+
bundle exec ruby starter.rb
13+
14+
The Ruby code will invoke the workflow which will execute two activities and return. The output of the final command
15+
should be:
16+
17+
```
18+
Executing workflow
19+
Workflow result: some-db-value from table some-db-table <appended-value>
20+
```
21+
22+
There is also a [test](../test/activity_simple/my_workflow_test.rb) that demonstrates mocking an activity during the
23+
test.

activity_simple/my_activities.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/activity'
4+
5+
module ActivitySimple
6+
module MyActivities
7+
# Fake database client
8+
class MyDatabaseClient
9+
def select_value(table)
10+
"some-db-value from table #{table}"
11+
end
12+
end
13+
14+
# Stateful activity that is created only once by worker creation code
15+
class SelectFromDatabase < Temporalio::Activity::Definition
16+
def initialize(db_client)
17+
@db_client = db_client
18+
end
19+
20+
def execute(table)
21+
@db_client.select_value(table)
22+
end
23+
end
24+
25+
# Stateless activity that is passed as class to worker creation code,
26+
# thereby instantiating every attempt
27+
class AppendSuffix < Temporalio::Activity::Definition
28+
def execute(append_to)
29+
"#{append_to} <appended-value>"
30+
end
31+
end
32+
end
33+
end

activity_simple/my_workflow.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/workflow'
4+
require_relative 'my_activities'
5+
6+
module ActivitySimple
7+
class MyWorkflow < Temporalio::Workflow::Definition
8+
def execute
9+
# Run an activity that needs some state like a database connection
10+
result1 = Temporalio::Workflow.execute_activity(
11+
MyActivities::SelectFromDatabase,
12+
'some-db-table',
13+
start_to_close_timeout: 5 * 60 # 5 minutes
14+
)
15+
Temporalio::Workflow.logger.info("Activity result 1: #{result1}")
16+
17+
# Run a stateless activity (note no difference on the caller side)
18+
result2 = Temporalio::Workflow.execute_activity(
19+
MyActivities::AppendSuffix,
20+
result1,
21+
start_to_close_timeout: 5 * 60
22+
)
23+
Temporalio::Workflow.logger.info("Activity result 2: #{result2}")
24+
25+
# We'll go ahead and return this result
26+
result2
27+
end
28+
end
29+
end

activity_simple/starter.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/client'
4+
require_relative 'my_workflow'
5+
6+
# Create a client
7+
client = Temporalio::Client.connect('localhost:7233', 'default')
8+
9+
# Run workflow
10+
puts 'Executing workflow'
11+
result = client.execute_workflow(
12+
ActivitySimple::MyWorkflow,
13+
id: 'activity-simple-sample-workflow-id',
14+
task_queue: 'activity-simple-sample'
15+
)
16+
puts "Workflow result: #{result}"

activity_simple/worker.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'my_activities'
4+
require_relative 'my_workflow'
5+
require 'logger'
6+
require 'temporalio/client'
7+
require 'temporalio/worker'
8+
9+
# Create a Temporal client
10+
client = Temporalio::Client.connect(
11+
'localhost:7233',
12+
'default',
13+
logger: Logger.new($stdout, level: Logger::INFO)
14+
)
15+
16+
# Use an instance for the stateful DB activity, other activity we will pass
17+
# in as class meaning it is instantiated each attempt
18+
db_client = ActivitySimple::MyActivities::MyDatabaseClient.new
19+
select_from_db_activity = ActivitySimple::MyActivities::SelectFromDatabase.new(db_client)
20+
21+
# Create worker with the activities and workflow
22+
worker = Temporalio::Worker.new(
23+
client:,
24+
task_queue: 'activity-simple-sample',
25+
activities: [select_from_db_activity, ActivitySimple::MyActivities::AppendSuffix],
26+
workflows: [ActivitySimple::MyWorkflow],
27+
workflow_executor: Temporalio::Worker::WorkflowExecutor::ThreadPool.default
28+
)
29+
30+
# Run the worker until SIGINT
31+
puts 'Starting worker (ctrl+c to exit)'
32+
worker.run(shutdown_signals: ['SIGINT'])

activity_worker/activity_worker.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# frozen_string_literal: true
22

3-
require_relative 'activity'
3+
require_relative 'say_hello_activity'
44
require 'temporalio/client'
55
require 'temporalio/worker'
66

@@ -14,7 +14,8 @@
1414
# By providing the class to the activity, it will be instantiated for every
1515
# attempt. If we provide an instance (e.g. SayHelloActivity.new), the same
1616
# instance is reused.
17-
activities: [ActivityWorker::SayHelloActivity]
17+
activities: [ActivityWorker::SayHelloActivity],
18+
workflow_executor: Temporalio::Worker::WorkflowExecutor::ThreadPool.default
1819
)
1920

2021
# Run the worker until SIGINT

0 commit comments

Comments
 (0)