temporal-ruby 0.0.0 → 0.0.1.pre.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|