Skip to content

Commit 2c75cee

Browse files
add frequent and periodic polling samples (#59)
* add frequent polling sample * add periodic polling sample * fix readme links * share mock service between polling examples
1 parent 9bbcc7c commit 2c75cee

19 files changed

+362
-29
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ Prerequisites:
2828
* [env_config](env_config) - Load client configuration from TOML files with programmatic overrides.
2929
* [message_passing_simple](message_passing_simple) - Simple workflow that accepts signals, queries, and updates.
3030
* [patching](patching) - Demonstrates how to safely alter a workflow.
31+
* [polling/frequent](polling/frequent) - Implement a frequent polling mechanism inside an Activity.
3132
* [polling/infrequent](polling/infrequent) - Implement an infrequent polling mechanism using Temporal's automatic Activity Retry feature.
33+
* [polling/periodic_sequence](polling/periodic_sequence) - Implement a periodic polling mechanism using a Child Workflow.
3234
* [rails_app](rails_app) - Basic Rails API application using Temporal workflows and activities.
3335
* [saga](saga) - Using undo/compensation using a very simplistic Saga pattern.
3436
* [sorbet_generic](sorbet_generic) - Proof of concept of how to do _advanced_ Sorbet typing with the SDK.

polling/frequent/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Frequent Polling Activity
2+
3+
This sample demonstrates how to implement a frequent polling mechanism
4+
(1 second or faster) inside an Activity.
5+
The implementation is a loop that polls a service and then sleeps for the poll
6+
interval (1 second in the sample).
7+
8+
## How to Run
9+
10+
1. **Start the Worker:**
11+
12+
Open a terminal and run the following command to start the worker process.
13+
The worker will listen for tasks on the `frequent-polling-sample` task queue.
14+
15+
```bash
16+
bundle exec ruby worker.rb
17+
```
18+
19+
You will see the worker log messages indicating it is calling the service.
20+
It will try several times, with a short delay between each attempt.
21+
22+
2. **Start the Workflow:**
23+
24+
In a separate terminal, run this command to start the workflow.
25+
This script will start the workflow and wait for its completion,
26+
printing the final result.
27+
28+
```bash
29+
bundle exec ruby starter.rb
30+
```
31+
32+
After a few seconds, the service will succeed.
33+
You will see the final result printed in the starter's terminal,
34+
and the worker will log the successful completion.
35+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/activity'
4+
require_relative '../test_service'
5+
6+
module Polling
7+
module Frequent
8+
class ComposeGreetingActivity < Temporalio::Activity::Definition
9+
def execute(input)
10+
loop do
11+
activity_info = Temporalio::Activity::Context.current.info
12+
begin
13+
return TestService.get_service_result(input, activity_info)
14+
rescue TestService::TestServiceError
15+
Temporalio::Activity::Context.current.logger.info('Test service was down')
16+
end
17+
Temporalio::Activity::Context.current.heartbeat
18+
sleep 1
19+
end
20+
end
21+
end
22+
end
23+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/workflow'
4+
require_relative 'compose_greeting_activity'
5+
6+
module Polling
7+
module Frequent
8+
class GreetingWorkflow < Temporalio::Workflow::Definition
9+
def execute(name)
10+
Temporalio::Workflow.execute_activity(
11+
ComposeGreetingActivity,
12+
{ greeting: 'Hello', name: name },
13+
start_to_close_timeout: 60,
14+
heartbeat_timeout: 2
15+
)
16+
end
17+
end
18+
end
19+
end

polling/frequent/starter.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/client'
4+
require_relative 'greeting_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+
Polling::Frequent::GreetingWorkflow,
13+
'World',
14+
id: "frequent-polling-sample-workflow-id-#{Time.now.to_i}",
15+
task_queue: 'frequent-polling-sample'
16+
)
17+
puts "Workflow result: #{result}"

polling/frequent/worker.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'greeting_workflow'
4+
require_relative 'compose_greeting_activity'
5+
require 'temporalio/client'
6+
require 'temporalio/worker'
7+
8+
# Create a client
9+
client = Temporalio::Client.connect('localhost:7233', 'default')
10+
11+
worker = Temporalio::Worker.new(
12+
client:,
13+
task_queue: 'frequent-polling-sample',
14+
workflows: [Polling::Frequent::GreetingWorkflow],
15+
activities: [Polling::Frequent::ComposeGreetingActivity]
16+
)
17+
18+
puts 'Starting worker (ctrl+c to exit)'
19+
worker.run(shutdown_signals: ['SIGINT'])

polling/infrequent/compose_greeting_activity.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
require 'temporalio/activity'
4-
require_relative 'test_service'
4+
require_relative '../test_service'
55

66
module Polling
77
module Infrequent

polling/infrequent/test_service.rb

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Periodic Polling of a Sequence of Activities
2+
3+
This sample demonstrates how to use a Child Workflow for periodic Activity polling.
4+
5+
This is a rare scenario where polling requires execution of a Sequence of Activities, or Activity arguments need to change between polling retries. For this case we use a Child Workflow to call polling activities a set number of times in a loop and then periodically call Continue-As-New.
6+
7+
## How to Run
8+
9+
To run, first see [README.md](../README.md) for prerequisites.
10+
11+
1. **Start the Worker:**
12+
13+
Open a terminal and run the following command to start the worker process.
14+
The worker will listen for tasks on the `frequent-polling-sample` task queue.
15+
16+
```bash
17+
bundle exec ruby worker.rb
18+
```
19+
20+
You will see the worker log messages indicating it is calling the service.
21+
It will try several times, with a short delay between each attempt.
22+
23+
2. **Start the Workflow:**
24+
25+
In a separate terminal, run this command to start the workflow.
26+
This script will start the workflow and wait for its completion,
27+
printing the final result.
28+
29+
```bash
30+
bundle exec ruby starter.rb
31+
```
32+
33+
After a few seconds, the service will succeed.
34+
You will see the final result printed in the starter's terminal,
35+
and the worker will log the successful completion.
36+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# frozen_string_literal: true
2+
3+
require 'temporalio/workflow'
4+
require_relative 'compose_greeting_activity'
5+
require_relative '../test_service'
6+
7+
module Polling
8+
module PeriodicSequence
9+
class ChildWorkflow < Temporalio::Workflow::Definition
10+
def execute(name)
11+
4.times do
12+
begin
13+
return Temporalio::Workflow.execute_activity(
14+
ComposeGreetingActivity,
15+
{ greeting: 'Hello', name: name },
16+
retry_policy: Temporalio::RetryPolicy.new(
17+
max_attempts: 1
18+
),
19+
start_to_close_timeout: 4
20+
)
21+
rescue Temporalio::Error::ActivityError
22+
Temporalio::Workflow.logger.info('Activity failed')
23+
end
24+
Temporalio::Workflow.sleep(1)
25+
end
26+
raise Temporalio::Workflow::ContinueAsNewError, name
27+
end
28+
end
29+
end
30+
end

0 commit comments

Comments
 (0)