temporal-ruby 0.0.0 → 0.0.1.pre.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -42
- data/lib/gen/temporal/api/command/v1/message_pb.rb +146 -0
- data/lib/gen/temporal/api/common/v1/message_pb.rb +67 -0
- data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +35 -0
- data/lib/gen/temporal/api/enums/v1/common_pb.rb +34 -0
- data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +62 -0
- data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +60 -0
- data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +31 -0
- data/lib/gen/temporal/api/enums/v1/query_pb.rb +31 -0
- data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +30 -0
- data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +82 -0
- data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +55 -0
- data/lib/gen/temporal/api/failure/v1/message_pb.rb +81 -0
- data/lib/gen/temporal/api/filter/v1/message_pb.rb +38 -0
- data/lib/gen/temporal/api/history/v1/message_pb.rb +423 -0
- data/lib/gen/temporal/api/namespace/v1/message_pb.rb +55 -0
- data/lib/gen/temporal/api/query/v1/message_pb.rb +36 -0
- data/lib/gen/temporal/api/replication/v1/message_pb.rb +27 -0
- data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +60 -0
- data/lib/gen/temporal/api/version/v1/message_pb.rb +28 -0
- data/lib/gen/temporal/api/workflow/v1/message_pb.rb +83 -0
- data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +538 -0
- data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +19 -0
- data/lib/gen/temporal/api/workflowservice/v1/service_services_pb.rb +223 -0
- data/lib/temporal-ruby.rb +1 -0
- data/lib/temporal.rb +137 -0
- data/lib/temporal/activity.rb +33 -0
- data/lib/temporal/activity/async_token.rb +34 -0
- data/lib/temporal/activity/context.rb +64 -0
- data/lib/temporal/activity/poller.rb +79 -0
- data/lib/temporal/activity/task_processor.rb +78 -0
- data/lib/temporal/activity/workflow_convenience_methods.rb +41 -0
- data/lib/temporal/client.rb +21 -0
- data/lib/temporal/client/errors.rb +8 -0
- data/lib/temporal/client/grpc_client.rb +345 -0
- data/lib/temporal/client/serializer.rb +31 -0
- data/lib/temporal/client/serializer/base.rb +23 -0
- data/lib/temporal/client/serializer/cancel_timer.rb +19 -0
- data/lib/temporal/client/serializer/complete_workflow.rb +20 -0
- data/lib/temporal/client/serializer/fail_workflow.rb +20 -0
- data/lib/temporal/client/serializer/failure.rb +29 -0
- data/lib/temporal/client/serializer/payload.rb +25 -0
- data/lib/temporal/client/serializer/record_marker.rb +23 -0
- data/lib/temporal/client/serializer/request_activity_cancellation.rb +19 -0
- data/lib/temporal/client/serializer/schedule_activity.rb +53 -0
- data/lib/temporal/client/serializer/start_child_workflow.rb +51 -0
- data/lib/temporal/client/serializer/start_timer.rb +20 -0
- data/lib/temporal/concerns/executable.rb +37 -0
- data/lib/temporal/concerns/typed.rb +40 -0
- data/lib/temporal/configuration.rb +44 -0
- data/lib/temporal/errors.rb +38 -0
- data/lib/temporal/executable_lookup.rb +25 -0
- data/lib/temporal/execution_options.rb +35 -0
- data/lib/temporal/json.rb +18 -0
- data/lib/temporal/metadata.rb +68 -0
- data/lib/temporal/metadata/activity.rb +27 -0
- data/lib/temporal/metadata/base.rb +17 -0
- data/lib/temporal/metadata/workflow.rb +22 -0
- data/lib/temporal/metadata/workflow_task.rb +25 -0
- data/lib/temporal/metrics.rb +37 -0
- data/lib/temporal/metrics_adapters/log.rb +33 -0
- data/lib/temporal/metrics_adapters/null.rb +9 -0
- data/lib/temporal/middleware/chain.rb +30 -0
- data/lib/temporal/middleware/entry.rb +9 -0
- data/lib/temporal/retry_policy.rb +27 -0
- data/lib/temporal/saga/concern.rb +23 -0
- data/lib/temporal/saga/result.rb +22 -0
- data/lib/temporal/saga/saga.rb +24 -0
- data/lib/temporal/testing.rb +50 -0
- data/lib/temporal/testing/future_registry.rb +27 -0
- data/lib/temporal/testing/local_activity_context.rb +17 -0
- data/lib/temporal/testing/local_workflow_context.rb +178 -0
- data/lib/temporal/testing/temporal_override.rb +121 -0
- data/lib/temporal/testing/workflow_execution.rb +44 -0
- data/lib/temporal/testing/workflow_override.rb +36 -0
- data/lib/temporal/thread_local_context.rb +14 -0
- data/lib/temporal/thread_pool.rb +63 -0
- data/lib/temporal/types.rb +7 -0
- data/lib/temporal/uuid.rb +19 -0
- data/lib/temporal/version.rb +1 -1
- data/lib/temporal/worker.rb +88 -0
- data/lib/temporal/workflow.rb +42 -0
- data/lib/temporal/workflow/command.rb +39 -0
- data/lib/temporal/workflow/command_state_machine.rb +48 -0
- data/lib/temporal/workflow/context.rb +243 -0
- data/lib/temporal/workflow/convenience_methods.rb +34 -0
- data/lib/temporal/workflow/dispatcher.rb +31 -0
- data/lib/temporal/workflow/execution_info.rb +51 -0
- data/lib/temporal/workflow/executor.rb +45 -0
- data/lib/temporal/workflow/future.rb +77 -0
- data/lib/temporal/workflow/history.rb +76 -0
- data/lib/temporal/workflow/history/event.rb +69 -0
- data/lib/temporal/workflow/history/event_target.rb +75 -0
- data/lib/temporal/workflow/history/window.rb +40 -0
- data/lib/temporal/workflow/poller.rb +67 -0
- data/lib/temporal/workflow/replay_aware_logger.rb +36 -0
- data/lib/temporal/workflow/state_manager.rb +342 -0
- data/lib/temporal/workflow/task_processor.rb +78 -0
- data/rbi/temporal-ruby.rbi +43 -0
- data/temporal.gemspec +10 -2
- metadata +186 -6
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# This module provides a set of methods for imitating direct Child Workflow calls
|
|
2
|
+
# from within Workflows:
|
|
3
|
+
#
|
|
4
|
+
# class TestWorkflow < Temporal::Workflow
|
|
5
|
+
# def execute
|
|
6
|
+
# ChildWorkflow.execute!('foo', 'bar')
|
|
7
|
+
# end
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# This is analogous to calling:
|
|
11
|
+
#
|
|
12
|
+
# workflow.execute_workflow(ChildWorkflow, 'foo', 'bar')
|
|
13
|
+
#
|
|
14
|
+
require 'temporal/thread_local_context'
|
|
15
|
+
|
|
16
|
+
module Temporal
|
|
17
|
+
class Workflow
|
|
18
|
+
module ConvenienceMethods
|
|
19
|
+
def execute(*input, **args)
|
|
20
|
+
context = Temporal::ThreadLocalContext.get
|
|
21
|
+
raise 'Called Workflow#execute outside of a Workflow context' unless context
|
|
22
|
+
|
|
23
|
+
context.execute_workflow(self, *input, **args)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def execute!(*input, **args)
|
|
27
|
+
context = Temporal::ThreadLocalContext.get
|
|
28
|
+
raise 'Called Workflow#execute! outside of a Workflow context' unless context
|
|
29
|
+
|
|
30
|
+
context.execute_workflow!(self, *input, **args)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Temporal
|
|
2
|
+
class Workflow
|
|
3
|
+
class Dispatcher
|
|
4
|
+
WILDCARD = '*'.freeze
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@handlers = Hash.new { |hash, key| hash[key] = [] }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def register_handler(target, event_name, &handler)
|
|
11
|
+
handlers[target] << [event_name, handler]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dispatch(target, event_name, args = nil)
|
|
15
|
+
handlers_for(target, event_name).each do |handler|
|
|
16
|
+
handler.call(*args)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
attr_reader :handlers
|
|
23
|
+
|
|
24
|
+
def handlers_for(target, event_name)
|
|
25
|
+
handlers[target]
|
|
26
|
+
.select { |(name, _)| name == event_name || name == WILDCARD }
|
|
27
|
+
.map(&:last)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Temporal
|
|
2
|
+
class Workflow
|
|
3
|
+
class ExecutionInfo < Struct.new(:workflow, :workflow_id, :run_id, :start_time, :close_time, :status, :history_length, keyword_init: true)
|
|
4
|
+
RUNNING_STATUS = :RUNNING
|
|
5
|
+
COMPLETED_STATUS = :COMPLETED
|
|
6
|
+
FAILED_STATUS = :FAILED
|
|
7
|
+
CANCELED_STATUS = :CANCELED
|
|
8
|
+
TERMINATED_STATUS = :TERMINATED
|
|
9
|
+
CONTINUED_AS_NEW_STATUS = :CONTINUED_AS_NEW
|
|
10
|
+
TIMED_OUT_STATUS = :TIMED_OUT
|
|
11
|
+
|
|
12
|
+
API_STATUS_MAP = {
|
|
13
|
+
WORKFLOW_EXECUTION_STATUS_RUNNING: RUNNING_STATUS,
|
|
14
|
+
WORKFLOW_EXECUTION_STATUS_COMPLETED: COMPLETED_STATUS,
|
|
15
|
+
WORKFLOW_EXECUTION_STATUS_FAILED: FAILED_STATUS,
|
|
16
|
+
WORKFLOW_EXECUTION_STATUS_CANCELED: CANCELED_STATUS,
|
|
17
|
+
WORKFLOW_EXECUTION_STATUS_TERMINATED: TERMINATED_STATUS,
|
|
18
|
+
WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW: CONTINUED_AS_NEW_STATUS,
|
|
19
|
+
WORKFLOW_EXECUTION_STATUS_TIMED_OUT: TIMED_OUT_STATUS
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
VALID_STATUSES = [
|
|
23
|
+
RUNNING_STATUS,
|
|
24
|
+
COMPLETED_STATUS,
|
|
25
|
+
FAILED_STATUS,
|
|
26
|
+
CANCELED_STATUS,
|
|
27
|
+
TERMINATED_STATUS,
|
|
28
|
+
CONTINUED_AS_NEW_STATUS,
|
|
29
|
+
TIMED_OUT_STATUS
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
def self.generate_from(response)
|
|
33
|
+
new(
|
|
34
|
+
workflow: response.type.name,
|
|
35
|
+
workflow_id: response.execution.workflow_id,
|
|
36
|
+
run_id: response.execution.run_id,
|
|
37
|
+
start_time: response.start_time&.to_time,
|
|
38
|
+
close_time: response.close_time&.to_time,
|
|
39
|
+
status: API_STATUS_MAP.fetch(response.status),
|
|
40
|
+
history_length: response.history_length,
|
|
41
|
+
).freeze
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
VALID_STATUSES.each do |status|
|
|
45
|
+
define_method("#{status.downcase}?") do
|
|
46
|
+
self.status == status
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'fiber'
|
|
2
|
+
|
|
3
|
+
require 'temporal/workflow/dispatcher'
|
|
4
|
+
require 'temporal/workflow/state_manager'
|
|
5
|
+
require 'temporal/workflow/context'
|
|
6
|
+
require 'temporal/workflow/history/event_target'
|
|
7
|
+
|
|
8
|
+
module Temporal
|
|
9
|
+
class Workflow
|
|
10
|
+
class Executor
|
|
11
|
+
def initialize(workflow_class, history)
|
|
12
|
+
@workflow_class = workflow_class
|
|
13
|
+
@dispatcher = Dispatcher.new
|
|
14
|
+
@state_manager = StateManager.new(dispatcher)
|
|
15
|
+
@history = history
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def run
|
|
19
|
+
dispatcher.register_handler(
|
|
20
|
+
History::EventTarget.workflow,
|
|
21
|
+
'started',
|
|
22
|
+
&method(:execute_workflow)
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
while window = history.next_window
|
|
26
|
+
state_manager.apply(window)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
return state_manager.commands
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
attr_reader :workflow_class, :dispatcher, :state_manager, :history
|
|
35
|
+
|
|
36
|
+
def execute_workflow(input, metadata)
|
|
37
|
+
context = Workflow::Context.new(state_manager, dispatcher, metadata)
|
|
38
|
+
|
|
39
|
+
Fiber.new do
|
|
40
|
+
workflow_class.execute_in_context(context, input)
|
|
41
|
+
end.resume
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'fiber'
|
|
2
|
+
|
|
3
|
+
module Temporal
|
|
4
|
+
class Workflow
|
|
5
|
+
class Future
|
|
6
|
+
attr_reader :target, :callbacks
|
|
7
|
+
|
|
8
|
+
def initialize(target, context, cancelation_id: nil)
|
|
9
|
+
@target = target
|
|
10
|
+
@context = context
|
|
11
|
+
@cancelation_id = cancelation_id
|
|
12
|
+
@callbacks = []
|
|
13
|
+
@ready = false
|
|
14
|
+
@failed = false
|
|
15
|
+
@result = nil
|
|
16
|
+
@exception = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def finished?
|
|
20
|
+
ready? || failed?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def ready?
|
|
24
|
+
@ready
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def failed?
|
|
28
|
+
@failed
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def wait
|
|
32
|
+
return if finished?
|
|
33
|
+
context.wait_for(self)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get
|
|
37
|
+
wait
|
|
38
|
+
exception || result
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def set(result)
|
|
42
|
+
raise 'can not fulfil a failed future' if failed?
|
|
43
|
+
|
|
44
|
+
@result = result
|
|
45
|
+
@ready = true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def fail(exception)
|
|
49
|
+
raise 'can not fail a fulfilled future' if ready?
|
|
50
|
+
|
|
51
|
+
@exception = exception
|
|
52
|
+
@failed = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def done(&block)
|
|
56
|
+
# do nothing
|
|
57
|
+
return if failed?
|
|
58
|
+
|
|
59
|
+
if ready?
|
|
60
|
+
block.call(result)
|
|
61
|
+
else
|
|
62
|
+
callbacks << block
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def cancel
|
|
67
|
+
return false if finished?
|
|
68
|
+
|
|
69
|
+
context.cancel(target, cancelation_id)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
attr_reader :context, :cancelation_id, :result, :exception
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'temporal/workflow/history/event'
|
|
2
|
+
require 'temporal/workflow/history/window'
|
|
3
|
+
|
|
4
|
+
module Temporal
|
|
5
|
+
class Workflow
|
|
6
|
+
class History
|
|
7
|
+
attr_reader :events
|
|
8
|
+
|
|
9
|
+
def initialize(events)
|
|
10
|
+
@events = events.map { |event| History::Event.new(event) }
|
|
11
|
+
@iterator = @events.each
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def last_completed_workflow_task
|
|
15
|
+
events.select { |event| event.type == 'WORKFLOW_TASK_COMPLETED' }.last
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# It is very important to replay the History window by window in order to
|
|
19
|
+
# simulate the exact same state the workflow was in when it processed the
|
|
20
|
+
# workflow task for the first time.
|
|
21
|
+
#
|
|
22
|
+
# A history window consists of 3 parts:
|
|
23
|
+
#
|
|
24
|
+
# 1. Events that happened since the last window (timer fired, activity completed, etc)
|
|
25
|
+
# 2. A workflow task related events (workflow task started, completed, failed, etc)
|
|
26
|
+
# 3. Commands issued by the last workflow task (^) (schedule activity, start timer, etc)
|
|
27
|
+
#
|
|
28
|
+
def next_window
|
|
29
|
+
return unless peek_event
|
|
30
|
+
|
|
31
|
+
window = History::Window.new
|
|
32
|
+
|
|
33
|
+
while event = next_event
|
|
34
|
+
window.add(event)
|
|
35
|
+
|
|
36
|
+
break if event.type == 'WORKFLOW_TASK_COMPLETED'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Find the end of the window by exhausting all the commands
|
|
40
|
+
window.add(next_event) while command?(peek_event)
|
|
41
|
+
|
|
42
|
+
window.freeze
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
COMMAND_EVENT_TYPES = %w[
|
|
48
|
+
ACTIVITY_TASK_SCHEDULED
|
|
49
|
+
ACTIVITY_TASK_CANCEL_REQUESTED
|
|
50
|
+
TIMER_STARTED
|
|
51
|
+
CANCEL_TIMER_FAILED
|
|
52
|
+
TIMER_CANCELED
|
|
53
|
+
WORKFLOW_EXECUTION_CANCEL_REQUESTED
|
|
54
|
+
START_CHILD_WORKFLOW_EXECUTION_INITIATED
|
|
55
|
+
SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED
|
|
56
|
+
REQUEST_CANCEL_ACTIVITY_TASK_FAILED
|
|
57
|
+
REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED
|
|
58
|
+
MARKER_RECORDED
|
|
59
|
+
].freeze
|
|
60
|
+
|
|
61
|
+
attr_reader :iterator
|
|
62
|
+
|
|
63
|
+
def next_event
|
|
64
|
+
iterator.next rescue nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def peek_event
|
|
68
|
+
iterator.peek rescue nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def command?(event)
|
|
72
|
+
COMMAND_EVENT_TYPES.include?(event&.type)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Temporal
|
|
2
|
+
class Workflow
|
|
3
|
+
class History
|
|
4
|
+
class Event
|
|
5
|
+
EVENT_TYPES = %w[
|
|
6
|
+
ACTIVITY_TASK_STARTED
|
|
7
|
+
ACTIVITY_TASK_COMPLETED
|
|
8
|
+
ACTIVITY_TASK_FAILED
|
|
9
|
+
ACTIVITY_TASK_TIMED_OUT
|
|
10
|
+
ACTIVITY_TASK_CANCELED
|
|
11
|
+
TIMER_FIRED
|
|
12
|
+
REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_FAILED
|
|
13
|
+
WORKFLOW_EXECUTION_SIGNALED
|
|
14
|
+
WORKFLOW_EXECUTION_TERMINATED
|
|
15
|
+
SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED
|
|
16
|
+
EXTERNAL_WORKFLOW_EXECUTION_CANCEL_REQUESTED
|
|
17
|
+
EXTERNAL_WORKFLOW_EXECUTION_SIGNALED
|
|
18
|
+
UPSERT_WORKFLOW_SEARCH_ATTRIBUTES
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
CHILD_WORKFLOW_EVENTS = %w[
|
|
22
|
+
START_CHILD_WORKFLOW_EXECUTION_FAILED
|
|
23
|
+
CHILD_WORKFLOW_EXECUTION_STARTED
|
|
24
|
+
CHILD_WORKFLOW_EXECUTION_COMPLETED
|
|
25
|
+
CHILD_WORKFLOW_EXECUTION_FAILED
|
|
26
|
+
CHILD_WORKFLOW_EXECUTION_CANCELED
|
|
27
|
+
CHILD_WORKFLOW_EXECUTION_TIMED_OUT
|
|
28
|
+
CHILD_WORKFLOW_EXECUTION_TERMINATED
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
PREFIX = 'EVENT_TYPE_'.freeze
|
|
32
|
+
|
|
33
|
+
attr_reader :id, :timestamp, :type, :attributes
|
|
34
|
+
|
|
35
|
+
def initialize(raw_event)
|
|
36
|
+
@id = raw_event.event_id
|
|
37
|
+
@timestamp = raw_event.event_time.to_time
|
|
38
|
+
@type = raw_event.event_type.to_s.gsub(PREFIX, '')
|
|
39
|
+
@attributes = extract_attributes(raw_event)
|
|
40
|
+
|
|
41
|
+
freeze
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the ID of the first event associated with the current event.
|
|
45
|
+
def originating_event_id
|
|
46
|
+
case type
|
|
47
|
+
when 'TIMER_FIRED'
|
|
48
|
+
attributes.started_event_id
|
|
49
|
+
when 'WORKFLOW_EXECUTION_SIGNALED'
|
|
50
|
+
1 # fixed id for everything related to current workflow
|
|
51
|
+
when *EVENT_TYPES
|
|
52
|
+
attributes.scheduled_event_id
|
|
53
|
+
when *CHILD_WORKFLOW_EVENTS
|
|
54
|
+
attributes.initiated_event_id
|
|
55
|
+
else
|
|
56
|
+
id
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def extract_attributes(raw_event)
|
|
63
|
+
attributes_name = raw_event.attributes
|
|
64
|
+
raw_event.public_send(attributes_name)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'temporal/errors'
|
|
2
|
+
|
|
3
|
+
module Temporal
|
|
4
|
+
class Workflow
|
|
5
|
+
class History
|
|
6
|
+
class EventTarget
|
|
7
|
+
class UnexpectedEventType < InternalError; end
|
|
8
|
+
|
|
9
|
+
ACTIVITY_TYPE = :activity
|
|
10
|
+
CANCEL_ACTIVITY_REQUEST_TYPE = :cancel_activity_request
|
|
11
|
+
TIMER_TYPE = :timer
|
|
12
|
+
CANCEL_TIMER_REQUEST_TYPE = :cancel_timer_request
|
|
13
|
+
CHILD_WORKFLOW_TYPE = :child_workflow
|
|
14
|
+
MARKER_TYPE = :marker
|
|
15
|
+
EXTERNAL_WORKFLOW_TYPE = :external_workflow
|
|
16
|
+
CANCEL_EXTERNAL_WORKFLOW_REQUEST_TYPE = :cancel_external_workflow_request
|
|
17
|
+
WORKFLOW_TYPE = :workflow
|
|
18
|
+
CANCEL_WORKFLOW_REQUEST_TYPE = :cancel_workflow_request
|
|
19
|
+
|
|
20
|
+
TARGET_TYPES = {
|
|
21
|
+
'ACTIVITY_TASK' => ACTIVITY_TYPE,
|
|
22
|
+
'ACTIVITY_TASK_CANCEL' => CANCEL_ACTIVITY_REQUEST_TYPE,
|
|
23
|
+
'REQUEST_CANCEL_ACTIVITY_TASK' => CANCEL_ACTIVITY_REQUEST_TYPE,
|
|
24
|
+
'TIMER' => TIMER_TYPE,
|
|
25
|
+
'CANCEL_TIMER' => CANCEL_TIMER_REQUEST_TYPE,
|
|
26
|
+
'CHILD_WORKFLOW_EXECUTION' => CHILD_WORKFLOW_TYPE,
|
|
27
|
+
'START_CHILD_WORKFLOW_EXECUTION' => CHILD_WORKFLOW_TYPE,
|
|
28
|
+
'MARKER' => MARKER_TYPE,
|
|
29
|
+
'EXTERNAL_WORKFLOW_EXECUTION' => EXTERNAL_WORKFLOW_TYPE,
|
|
30
|
+
'SIGNAL_EXTERNAL_WORKFLOW_EXECUTION' => EXTERNAL_WORKFLOW_TYPE,
|
|
31
|
+
'EXTERNAL_WORKFLOW_EXECUTION_CANCEL' => CANCEL_EXTERNAL_WORKFLOW_REQUEST_TYPE,
|
|
32
|
+
'REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION' => CANCEL_EXTERNAL_WORKFLOW_REQUEST_TYPE,
|
|
33
|
+
'UPSERT_WORKFLOW_SEARCH_ATTRIBUTES' => WORKFLOW_TYPE,
|
|
34
|
+
'WORKFLOW_EXECUTION' => WORKFLOW_TYPE,
|
|
35
|
+
'WORKFLOW_EXECUTION_CANCEL' => CANCEL_WORKFLOW_REQUEST_TYPE,
|
|
36
|
+
}.freeze
|
|
37
|
+
|
|
38
|
+
attr_reader :id, :type
|
|
39
|
+
|
|
40
|
+
def self.workflow
|
|
41
|
+
@workflow ||= new(1, WORKFLOW_TYPE)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.from_event(event)
|
|
45
|
+
_, target_type = TARGET_TYPES.find { |type, _| event.type.start_with?(type) }
|
|
46
|
+
|
|
47
|
+
unless target_type
|
|
48
|
+
raise UnexpectedEventType, "Unexpected event #{event.type}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
new(event.originating_event_id, target_type)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def initialize(id, type)
|
|
55
|
+
@id = id
|
|
56
|
+
@type = type
|
|
57
|
+
|
|
58
|
+
freeze
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def ==(other)
|
|
62
|
+
id == other.id && type == other.type
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def eql?(other)
|
|
66
|
+
self == other
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def hash
|
|
70
|
+
[id, type].hash
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|