amit-temporalio 0.3.0-x86_64-darwin

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.
Files changed (175) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +2 -0
  3. data/Gemfile +23 -0
  4. data/Rakefile +101 -0
  5. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  6. data/lib/temporalio/activity/context.rb +116 -0
  7. data/lib/temporalio/activity/definition.rb +189 -0
  8. data/lib/temporalio/activity/info.rb +64 -0
  9. data/lib/temporalio/activity.rb +12 -0
  10. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  11. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  12. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  13. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +126 -0
  14. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  15. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  16. data/lib/temporalio/api/cloud/identity/v1/message.rb +41 -0
  17. data/lib/temporalio/api/cloud/namespace/v1/message.rb +42 -0
  18. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  19. data/lib/temporalio/api/cloud/operation/v1/message.rb +28 -0
  20. data/lib/temporalio/api/cloud/region/v1/message.rb +24 -0
  21. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  22. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  23. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  24. data/lib/temporalio/api/command/v1/message.rb +46 -0
  25. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  26. data/lib/temporalio/api/common/v1/message.rb +47 -0
  27. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  28. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  29. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  30. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  31. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  32. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  33. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  34. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  35. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  36. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  37. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  38. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  39. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  40. data/lib/temporalio/api/export/v1/message.rb +24 -0
  41. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  42. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  43. data/lib/temporalio/api/history/v1/message.rb +90 -0
  44. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  45. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  46. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  47. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  48. data/lib/temporalio/api/operatorservice.rb +3 -0
  49. data/lib/temporalio/api/payload_visitor.rb +1513 -0
  50. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  51. data/lib/temporalio/api/query/v1/message.rb +27 -0
  52. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  53. data/lib/temporalio/api/schedule/v1/message.rb +43 -0
  54. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  55. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  56. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  57. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  58. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  59. data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
  60. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  61. data/lib/temporalio/api/update/v1/message.rb +33 -0
  62. data/lib/temporalio/api/version/v1/message.rb +26 -0
  63. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  64. data/lib/temporalio/api/workflowservice/v1/request_response.rb +204 -0
  65. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  66. data/lib/temporalio/api/workflowservice.rb +3 -0
  67. data/lib/temporalio/api.rb +14 -0
  68. data/lib/temporalio/cancellation.rb +170 -0
  69. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  70. data/lib/temporalio/client/async_activity_handle.rb +85 -0
  71. data/lib/temporalio/client/connection/cloud_service.rb +726 -0
  72. data/lib/temporalio/client/connection/operator_service.rb +201 -0
  73. data/lib/temporalio/client/connection/service.rb +42 -0
  74. data/lib/temporalio/client/connection/test_service.rb +111 -0
  75. data/lib/temporalio/client/connection/workflow_service.rb +1041 -0
  76. data/lib/temporalio/client/connection.rb +316 -0
  77. data/lib/temporalio/client/interceptor.rb +416 -0
  78. data/lib/temporalio/client/schedule.rb +967 -0
  79. data/lib/temporalio/client/schedule_handle.rb +126 -0
  80. data/lib/temporalio/client/workflow_execution.rb +100 -0
  81. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  82. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  83. data/lib/temporalio/client/workflow_handle.rb +389 -0
  84. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  85. data/lib/temporalio/client/workflow_update_handle.rb +65 -0
  86. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  87. data/lib/temporalio/client.rb +484 -0
  88. data/lib/temporalio/common_enums.rb +41 -0
  89. data/lib/temporalio/converters/data_converter.rb +99 -0
  90. data/lib/temporalio/converters/failure_converter.rb +202 -0
  91. data/lib/temporalio/converters/payload_codec.rb +26 -0
  92. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  93. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  94. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  95. data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
  96. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  97. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  98. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  99. data/lib/temporalio/converters/payload_converter.rb +71 -0
  100. data/lib/temporalio/converters/raw_value.rb +20 -0
  101. data/lib/temporalio/converters.rb +9 -0
  102. data/lib/temporalio/error/failure.rb +219 -0
  103. data/lib/temporalio/error.rb +155 -0
  104. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  105. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  106. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  107. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  108. data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
  109. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  110. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  111. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
  112. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
  113. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  114. data/lib/temporalio/internal/bridge/api.rb +3 -0
  115. data/lib/temporalio/internal/bridge/client.rb +95 -0
  116. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  117. data/lib/temporalio/internal/bridge/temporalio_bridge.bundle +0 -0
  118. data/lib/temporalio/internal/bridge/testing.rb +66 -0
  119. data/lib/temporalio/internal/bridge/worker.rb +85 -0
  120. data/lib/temporalio/internal/bridge.rb +36 -0
  121. data/lib/temporalio/internal/client/implementation.rb +700 -0
  122. data/lib/temporalio/internal/metric.rb +122 -0
  123. data/lib/temporalio/internal/proto_utils.rb +133 -0
  124. data/lib/temporalio/internal/worker/activity_worker.rb +376 -0
  125. data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
  126. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  127. data/lib/temporalio/internal/worker/workflow_instance/context.rb +333 -0
  128. data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
  129. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  130. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  131. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  132. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  133. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  134. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  135. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
  136. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  137. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  138. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
  139. data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
  140. data/lib/temporalio/internal/worker/workflow_worker.rb +236 -0
  141. data/lib/temporalio/internal.rb +7 -0
  142. data/lib/temporalio/metric.rb +109 -0
  143. data/lib/temporalio/retry_policy.rb +74 -0
  144. data/lib/temporalio/runtime.rb +314 -0
  145. data/lib/temporalio/scoped_logger.rb +96 -0
  146. data/lib/temporalio/search_attributes.rb +343 -0
  147. data/lib/temporalio/testing/activity_environment.rb +136 -0
  148. data/lib/temporalio/testing/workflow_environment.rb +383 -0
  149. data/lib/temporalio/testing.rb +10 -0
  150. data/lib/temporalio/version.rb +5 -0
  151. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  152. data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
  153. data/lib/temporalio/worker/activity_executor.rb +55 -0
  154. data/lib/temporalio/worker/interceptor.rb +362 -0
  155. data/lib/temporalio/worker/thread_pool.rb +237 -0
  156. data/lib/temporalio/worker/tuner.rb +189 -0
  157. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
  158. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  159. data/lib/temporalio/worker/workflow_replayer.rb +343 -0
  160. data/lib/temporalio/worker.rb +569 -0
  161. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  162. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  163. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  164. data/lib/temporalio/workflow/definition.rb +566 -0
  165. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  166. data/lib/temporalio/workflow/future.rb +151 -0
  167. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  168. data/lib/temporalio/workflow/info.rb +82 -0
  169. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  170. data/lib/temporalio/workflow/update_info.rb +20 -0
  171. data/lib/temporalio/workflow.rb +529 -0
  172. data/lib/temporalio/workflow_history.rb +47 -0
  173. data/lib/temporalio.rb +11 -0
  174. data/temporalio.gemspec +28 -0
  175. metadata +236 -0
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/client/interceptor'
4
+ require 'temporalio/client/schedule'
5
+
6
+ module Temporalio
7
+ class Client
8
+ # Handle for interacting with a schedule. This is usually created via {Client.create_schedule} or
9
+ # {Client.schedule_handle}.
10
+ class ScheduleHandle
11
+ # @return [String] ID of the schedule.
12
+ attr_reader :id
13
+
14
+ # @!visibility private
15
+ def initialize(client:, id:)
16
+ @client = client
17
+ @id = id
18
+ end
19
+
20
+ # Backfill the schedule by going through the specified time periods as if they passed right now.
21
+ #
22
+ # @param backfills [Array<Schedule::Backfill>] Backfill periods.
23
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
24
+ #
25
+ # @raise [Error::RPCError] RPC error from call.
26
+ def backfill(
27
+ *backfills,
28
+ rpc_options: nil
29
+ )
30
+ raise ArgumentError, 'At least one backfill required' if backfills.empty?
31
+
32
+ @client._impl.backfill_schedule(Interceptor::BackfillScheduleInput.new(
33
+ id:,
34
+ backfills:,
35
+ rpc_options:
36
+ ))
37
+ end
38
+
39
+ # Delete this schedule.
40
+ #
41
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
42
+ #
43
+ # @raise [Error::RPCError] RPC error from call.
44
+ def delete(rpc_options: nil)
45
+ @client._impl.delete_schedule(Interceptor::DeleteScheduleInput.new(
46
+ id:,
47
+ rpc_options:
48
+ ))
49
+ end
50
+
51
+ # Fetch this schedule's description.
52
+ #
53
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
54
+ #
55
+ # @return [Schedule::Description] Schedule description.
56
+ # @raise [Error::RPCError] RPC error from call.
57
+ def describe(rpc_options: nil)
58
+ @client._impl.describe_schedule(Interceptor::DescribeScheduleInput.new(
59
+ id:,
60
+ rpc_options:
61
+ ))
62
+ end
63
+
64
+ # Pause the schedule and set a note.
65
+ #
66
+ # @param note [String] Note to set on the schedule.
67
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
68
+ #
69
+ # @raise [Error::RPCError] RPC error from call.
70
+ def pause(note: 'Paused via Ruby SDK', rpc_options: nil)
71
+ @client._impl.pause_schedule(Interceptor::PauseScheduleInput.new(
72
+ id:,
73
+ note:,
74
+ rpc_options:
75
+ ))
76
+ end
77
+
78
+ # Trigger an action on this schedule to happen immediately.
79
+ #
80
+ # @param overlap [Schedule::OverlapPolicy, nil] If set, overrides the schedule's overlap policy.
81
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
82
+ #
83
+ # @raise [Error::RPCError] RPC error from call.
84
+ def trigger(overlap: nil, rpc_options: nil)
85
+ @client._impl.trigger_schedule(Interceptor::TriggerScheduleInput.new(
86
+ id:,
87
+ overlap:,
88
+ rpc_options:
89
+ ))
90
+ end
91
+
92
+ # Unpause the schedule and set a note.
93
+ #
94
+ # @param note [String] Note to set on the schedule.
95
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
96
+ #
97
+ # @raise [Error::RPCError] RPC error from call.
98
+ def unpause(note: 'Unpaused via Ruby SDK', rpc_options: nil)
99
+ @client._impl.unpause_schedule(Interceptor::UnpauseScheduleInput.new(
100
+ id:,
101
+ note:,
102
+ rpc_options:
103
+ ))
104
+ end
105
+
106
+ # Update a schedule using a callback to build the update from the description.
107
+ #
108
+ # NOTE: In future versions, the callback may be invoked multiple times in a conflict-resolution loop.
109
+ #
110
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
111
+ # @yield Block called to obtain the update.
112
+ # @yieldparam [Schedule::Update::Input] Parameter to the block that contains a description with the schedule to be
113
+ # updated.
114
+ # @yieldreturn [Schedule::Update, nil] The update to apply, or `nil` to not perform an update.
115
+ #
116
+ # @raise [Error::RPCError] RPC error from call.
117
+ def update(rpc_options: nil, &updater)
118
+ @client._impl.update_schedule(Interceptor::UpdateScheduleInput.new(
119
+ id:,
120
+ updater:,
121
+ rpc_options:
122
+ ))
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/api'
4
+ require 'temporalio/client/workflow_execution_status'
5
+ require 'temporalio/internal/proto_utils'
6
+ require 'temporalio/search_attributes'
7
+
8
+ module Temporalio
9
+ class Client
10
+ # Info for a single workflow execution run.
11
+ class WorkflowExecution
12
+ # @return [Api::Workflow::V1::WorkflowExecutionInfo] Underlying protobuf info.
13
+ attr_reader :raw_info
14
+
15
+ # @!visibility private
16
+ def initialize(raw_info, data_converter)
17
+ @raw_info = raw_info
18
+ @memo = Internal::ProtoUtils::LazyMemo.new(raw_info.memo, data_converter)
19
+ @search_attributes = Internal::ProtoUtils::LazySearchAttributes.new(raw_info.search_attributes)
20
+ end
21
+
22
+ # @return [Time, nil] When the workflow was closed if closed.
23
+ def close_time
24
+ Internal::ProtoUtils.timestamp_to_time(@raw_info.close_time)
25
+ end
26
+
27
+ # @return [Time, nil] When this workflow run started or should start.
28
+ def execution_time
29
+ Internal::ProtoUtils.timestamp_to_time(@raw_info.execution_time)
30
+ end
31
+
32
+ # @return [Integer] Number of events in the history.
33
+ def history_length
34
+ @raw_info.history_length
35
+ end
36
+
37
+ # @return [String] ID for the workflow.
38
+ def id
39
+ @raw_info.execution.workflow_id
40
+ end
41
+
42
+ # @return [Hash<String, Object>, nil] Memo for the workflow.
43
+ def memo
44
+ @memo.get
45
+ end
46
+
47
+ # @return [String, nil] ID for the parent workflow if this was started as a child.
48
+ def parent_id
49
+ @raw_info.parent_execution&.workflow_id
50
+ end
51
+
52
+ # @return [String, nil] Run ID for the parent workflow if this was started as a child.
53
+ def parent_run_id
54
+ @raw_info.parent_execution&.run_id
55
+ end
56
+
57
+ # @return [String] Run ID for this workflow run.
58
+ def run_id
59
+ @raw_info.execution.run_id
60
+ end
61
+
62
+ # @return [SearchAttributes, nil] Current set of search attributes if any.
63
+ def search_attributes
64
+ @search_attributes.get
65
+ end
66
+
67
+ # @return [Time] When the workflow was created.
68
+ def start_time
69
+ Internal::ProtoUtils.timestamp_to_time(@raw_info.start_time) || raise # Never nil
70
+ end
71
+
72
+ # @return [WorkflowExecutionStatus] Status for the workflow.
73
+ def status
74
+ Internal::ProtoUtils.enum_to_int(Api::Enums::V1::WorkflowExecutionStatus, @raw_info.status)
75
+ end
76
+
77
+ # @return [String] Task queue for the workflow.
78
+ def task_queue
79
+ @raw_info.task_queue
80
+ end
81
+
82
+ # @return [String] Type name for the workflow.
83
+ def workflow_type
84
+ @raw_info.type.name
85
+ end
86
+
87
+ # Description for a single workflow execution run.
88
+ class Description < WorkflowExecution
89
+ # @return [Api::WorkflowService::V1::DescribeWorkflowExecutionResponse] Underlying protobuf description.
90
+ attr_reader :raw_description
91
+
92
+ # @!visibility private
93
+ def initialize(raw_description, data_converter)
94
+ super(raw_description.workflow_execution_info, data_converter)
95
+ @raw_description = raw_description
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ class Client
5
+ # Representation of a count from a count workflows call.
6
+ class WorkflowExecutionCount
7
+ # @return [Integer] Approximate number of workflows matching the original query. If the query had a group-by
8
+ # clause, this is simply the sum of all the counts in {groups}.
9
+ attr_reader :count
10
+
11
+ # @return [Array<AggregationGroup>] Groups if the query had a group-by clause, or empty if not.
12
+ attr_reader :groups
13
+
14
+ # @!visibility private
15
+ def initialize(count, groups)
16
+ @count = count
17
+ @groups = groups
18
+ end
19
+
20
+ # Aggregation group if the workflow count query had a group-by clause.
21
+ class AggregationGroup
22
+ # @return [Integer] Approximate number of workflows matching the original query for this group.
23
+ attr_reader :count
24
+
25
+ # @return [Array<Object>] Search attribute values for this group.
26
+ attr_reader :group_values
27
+
28
+ # @!visibility private
29
+ def initialize(count, group_values)
30
+ @count = count
31
+ @group_values = group_values
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/api'
4
+
5
+ module Temporalio
6
+ class Client
7
+ # Status of a workflow execution.
8
+ module WorkflowExecutionStatus
9
+ RUNNING = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_RUNNING
10
+ COMPLETED = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_COMPLETED
11
+ FAILED = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_FAILED
12
+ CANCELED = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_CANCELED
13
+ TERMINATED = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_TERMINATED
14
+ CONTINUED_AS_NEW = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW
15
+ TIMED_OUT = Api::Enums::V1::WorkflowExecutionStatus::WORKFLOW_EXECUTION_STATUS_TIMED_OUT
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,389 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+ require 'temporalio/api'
5
+ require 'temporalio/client/interceptor'
6
+ require 'temporalio/client/workflow_update_handle'
7
+ require 'temporalio/client/workflow_update_wait_stage'
8
+ require 'temporalio/error'
9
+ require 'temporalio/workflow_history'
10
+
11
+ module Temporalio
12
+ class Client
13
+ # Handle for interacting with a workflow. This is usually created via {Client.start_workflow} or
14
+ # {Client.workflow_handle}.
15
+ class WorkflowHandle
16
+ # @return [String] ID for the workflow.
17
+ attr_reader :id
18
+
19
+ # Run ID used for {signal}, {query}, and {start_update}/{execute_update} calls if present to ensure the
20
+ # signal/query/update happen on this exact run.
21
+ #
22
+ # This is only created via {Client.workflow_handle}. {Client.start_workflow} will not set this value.
23
+ #
24
+ # This cannot be mutated. If a different run ID is needed, {Client.workflow_handle} must be used instead.
25
+ #
26
+ # @return [String, nil] Run ID.
27
+ attr_reader :run_id
28
+
29
+ # Run ID used for {result} calls if present to ensure result is for a workflow starting from this run.
30
+ #
31
+ # When this handle is created via {Client.workflow_handle}, this is the same as {run_id}. When this handle is
32
+ # created via {Client.start_workflow}, this value will be the resulting run ID.
33
+ #
34
+ # This cannot be mutated. If a different run ID is needed, {Client.workflow_handle} must be used instead.
35
+ #
36
+ # @return [String, nil] Result run ID.
37
+ attr_reader :result_run_id
38
+
39
+ # Run ID used for some calls like {cancel} and {terminate} to ensure the cancel and terminate happen for a
40
+ # workflow ID on a chain started with this run ID.
41
+ #
42
+ # This can be set when using {Client.workflow_handle}. When {Client.start_workflow} is called without a start
43
+ # signal, this is set to the resulting run.
44
+ #
45
+ # This cannot be mutated. If a different first execution run ID is needed, {Client.workflow_handle} must be used
46
+ # instead.
47
+ #
48
+ # @return [String, nil] First execution run ID.
49
+ attr_reader :first_execution_run_id
50
+
51
+ # @!visibility private
52
+ def initialize(client:, id:, run_id:, result_run_id:, first_execution_run_id:)
53
+ @client = client
54
+ @id = id
55
+ @run_id = run_id
56
+ @result_run_id = result_run_id
57
+ @first_execution_run_id = first_execution_run_id
58
+ end
59
+
60
+ # Wait for the result of the workflow.
61
+ #
62
+ # This will use {result_run_id} if present to base the result on. To use another run ID, a new handle must be
63
+ # created via {Client.workflow_handle}.
64
+ #
65
+ # @param follow_runs [Boolean] If +true+, workflow runs will be continually fetched across retries and continue as
66
+ # new until the latest one is found. If +false+, the first result is used.
67
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
68
+ #
69
+ # @return [Object] Result of the workflow after being converted by the data converter.
70
+ #
71
+ # @raise [Error::WorkflowFailedError] Workflow failed with +cause+ as the cause.
72
+ # @raise [Error::WorkflowContinuedAsNewError] Workflow continued as new and +follow_runs+ is +false+.
73
+ # @raise [Error::RPCError] RPC error from call.
74
+ def result(follow_runs: true, rpc_options: nil)
75
+ # Wait on the close event, following as needed
76
+ hist_run_id = result_run_id
77
+ loop do
78
+ # Get close event
79
+ event = fetch_history_events(
80
+ wait_new_event: true,
81
+ event_filter_type: Api::Enums::V1::HistoryEventFilterType::HISTORY_EVENT_FILTER_TYPE_CLOSE_EVENT,
82
+ skip_archival: true,
83
+ specific_run_id: hist_run_id,
84
+ rpc_options:
85
+ ).next
86
+
87
+ # Check each close type'
88
+ case event.event_type
89
+ when :EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED
90
+ attrs = event.workflow_execution_completed_event_attributes
91
+ hist_run_id = attrs.new_execution_run_id
92
+ next if follow_runs && hist_run_id && !hist_run_id.empty?
93
+
94
+ return @client.data_converter.from_payloads(attrs.result).first
95
+ when :EVENT_TYPE_WORKFLOW_EXECUTION_FAILED
96
+ attrs = event.workflow_execution_failed_event_attributes
97
+ hist_run_id = attrs.new_execution_run_id
98
+ next if follow_runs && hist_run_id && !hist_run_id.empty?
99
+
100
+ raise Error::WorkflowFailedError.new, cause: @client.data_converter.from_failure(attrs.failure)
101
+ when :EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED
102
+ attrs = event.workflow_execution_canceled_event_attributes
103
+ raise Error::WorkflowFailedError.new, 'Workflow execution canceled', cause: Error::CanceledError.new(
104
+ 'Workflow execution canceled',
105
+ details: @client.data_converter.from_payloads(attrs&.details)
106
+ )
107
+ when :EVENT_TYPE_WORKFLOW_EXECUTION_TERMINATED
108
+ attrs = event.workflow_execution_terminated_event_attributes
109
+ raise Error::WorkflowFailedError.new, 'Workflow execution terminated', cause: Error::TerminatedError.new(
110
+ Internal::ProtoUtils.string_or(attrs.reason, 'Workflow execution terminated'),
111
+ details: @client.data_converter.from_payloads(attrs&.details)
112
+ )
113
+ when :EVENT_TYPE_WORKFLOW_EXECUTION_TIMED_OUT
114
+ attrs = event.workflow_execution_timed_out_event_attributes
115
+ hist_run_id = attrs.new_execution_run_id
116
+ next if follow_runs && hist_run_id && !hist_run_id.empty?
117
+
118
+ raise Error::WorkflowFailedError.new, 'Workflow execution timed out', cause: Error::TimeoutError.new(
119
+ 'Workflow execution timed out',
120
+ type: Api::Enums::V1::TimeoutType::TIMEOUT_TYPE_START_TO_CLOSE,
121
+ last_heartbeat_details: []
122
+ )
123
+ when :EVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW
124
+ attrs = event.workflow_execution_continued_as_new_event_attributes
125
+ hist_run_id = attrs.new_execution_run_id
126
+ next if follow_runs && hist_run_id && !hist_run_id.empty?
127
+
128
+ # TODO: Use more specific error and decode failure
129
+ raise Error::WorkflowContinuedAsNewError.new(new_run_id: attrs.new_execution_run_id)
130
+ else
131
+ raise Error, "Unknown close event type: #{event.event_type}"
132
+ end
133
+ end
134
+ end
135
+
136
+ # Get workflow details. This will get details for the {run_id} if present. To use a different run ID, create a new
137
+ # handle via {Client.workflow_handle}.
138
+ #
139
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
140
+ #
141
+ # @return [WorkflowExecution::Description] Workflow description.
142
+ #
143
+ # @raise [Error::RPCError] RPC error from call.
144
+ #
145
+ # @note Handles created as a result of {Client.start_workflow} will describe the latest workflow with the same
146
+ # workflow ID even if it is unrelated to the started workflow.
147
+ def describe(rpc_options: nil)
148
+ @client._impl.describe_workflow(Interceptor::DescribeWorkflowInput.new(
149
+ workflow_id: id,
150
+ run_id:,
151
+ rpc_options:
152
+ ))
153
+ end
154
+
155
+ # Get workflow history. This is a helper on top of {fetch_history_events}.
156
+ #
157
+ # @param event_filter_type [Api::Enums::V1::HistoryEventFilterType] Types of events to fetch.
158
+ # @param skip_archival [Boolean] Whether to skip archival.
159
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
160
+ #
161
+ # @return [WorkflowHistory] Workflow history.
162
+ #
163
+ # @raise [Error::RPCError] RPC error from call.
164
+ def fetch_history(
165
+ event_filter_type: Api::Enums::V1::HistoryEventFilterType::HISTORY_EVENT_FILTER_TYPE_ALL_EVENT,
166
+ skip_archival: false,
167
+ rpc_options: nil
168
+ )
169
+ WorkflowHistory.new(
170
+ fetch_history_events(
171
+ event_filter_type:,
172
+ skip_archival:,
173
+ rpc_options:
174
+ ).to_a
175
+ )
176
+ end
177
+
178
+ # Fetch an enumerator of history events for this workflow. Internally this is done in paginated form, but it is
179
+ # presented as an enumerator.
180
+ #
181
+ # @param wait_new_event [Boolean] If +true+, when the end of the current set of events is reached but the workflow
182
+ # is not complete, this will wait for the next event. If +false+, the enumerable completes at the end of current
183
+ # history.
184
+ # @param event_filter_type [Api::Enums::V1::HistoryEventFilterType] Types of events to fetch.
185
+ # @param skip_archival [Boolean] Whether to skip archival.
186
+ # @param specific_run_id [String, nil] Run ID to fetch events for. Default is the {run_id}. Most users will not
187
+ # need to set this and instead use the one on the class.
188
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
189
+ #
190
+ # @return [Enumerator<Api::History::V1::HistoryEvent>] Enumerable events.
191
+ #
192
+ # @raise [Error::RPCError] RPC error from call.
193
+ def fetch_history_events(
194
+ wait_new_event: false,
195
+ event_filter_type: Api::Enums::V1::HistoryEventFilterType::HISTORY_EVENT_FILTER_TYPE_ALL_EVENT,
196
+ skip_archival: false,
197
+ specific_run_id: run_id,
198
+ rpc_options: nil
199
+ )
200
+ @client._impl.fetch_workflow_history_events(Interceptor::FetchWorkflowHistoryEventsInput.new(
201
+ workflow_id: id,
202
+ run_id: specific_run_id,
203
+ wait_new_event:,
204
+ event_filter_type:,
205
+ skip_archival:,
206
+ rpc_options:
207
+ ))
208
+ end
209
+
210
+ # Send a signal to the workflow. This will signal for {run_id} if present. To use a different run ID, create a new
211
+ # handle via {Client.workflow_handle}.
212
+ #
213
+ # @param signal [Workflow::Definition::Signal, Symbol, String] Signal definition or name.
214
+ # @param args [Array<Object>] Signal arguments.
215
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
216
+ #
217
+ # @raise [Error::RPCError] RPC error from call.
218
+ #
219
+ # @note Handles created as a result of {Client.start_workflow} will signal the latest workflow with the same
220
+ # workflow ID even if it is unrelated to the started workflow.
221
+ def signal(signal, *args, rpc_options: nil)
222
+ @client._impl.signal_workflow(Interceptor::SignalWorkflowInput.new(
223
+ workflow_id: id,
224
+ run_id:,
225
+ signal:,
226
+ args:,
227
+ headers: {},
228
+ rpc_options:
229
+ ))
230
+ end
231
+
232
+ # Query the workflow. This will query for {run_id} if present. To use a different run ID, create a new handle via
233
+ # {Client.workflow_handle}.
234
+ #
235
+ # @param query [Workflow::Definition::Query, Symbol, String] Query definition or name.
236
+ # @param args [Array<Object>] Query arguments.
237
+ # @param reject_condition [WorkflowQueryRejectCondition, nil] Condition for rejecting the query.
238
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
239
+ #
240
+ # @return [Object, nil] Query result.
241
+ #
242
+ # @raise [Error::WorkflowQueryFailedError] The query on the workflow returned a failure.
243
+ # @raise [Error::WorkflowQueryRejectedError] A query reject condition was satisfied.
244
+ # @raise [Error::RPCError] RPC error from call.
245
+ #
246
+ # @note Handles created as a result of {Client.start_workflow} will query the latest workflow with the same
247
+ # workflow ID even if it is unrelated to the started workflow.
248
+ def query(
249
+ query,
250
+ *args,
251
+ reject_condition: @client.options.default_workflow_query_reject_condition,
252
+ rpc_options: nil
253
+ )
254
+ @client._impl.query_workflow(Interceptor::QueryWorkflowInput.new(
255
+ workflow_id: id,
256
+ run_id:,
257
+ query:,
258
+ args:,
259
+ reject_condition:,
260
+ headers: {},
261
+ rpc_options:
262
+ ))
263
+ end
264
+
265
+ # Send an update request to the workflow and return a handle to it. This will target the workflow with {run_id} if
266
+ # present. To use a different run ID, create a new handle via {Client.workflow_handle}.
267
+ #
268
+ # @param update [Workflow::Definition::Update, Symbol, String] Update definition or name.
269
+ # @param args [Array<Object>] Update arguments.
270
+ # @param wait_for_stage [WorkflowUpdateWaitStage] Required stage to wait until returning. ADMITTED is not
271
+ # currently supported. See https://docs.temporal.io/workflows#update for more details.
272
+ # @param id [String] ID of the update.
273
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
274
+ #
275
+ # @return [WorkflowUpdateHandle] The update handle.
276
+ #
277
+ # @raise [Error::WorkflowUpdateRPCTimeoutOrCanceledError] This update call timed out or was canceled. This doesn't
278
+ # mean the update itself was timed out or canceled.
279
+ # @raise [Error::RPCError] RPC error from call.
280
+ #
281
+ # @note Handles created as a result of {Client.start_workflow} will send updates the latest workflow with the same
282
+ # workflow ID even if it is unrelated to the started workflow.
283
+ def start_update(
284
+ update,
285
+ *args,
286
+ wait_for_stage:,
287
+ id: SecureRandom.uuid,
288
+ rpc_options: nil
289
+ )
290
+ @client._impl.start_workflow_update(Interceptor::StartWorkflowUpdateInput.new(
291
+ workflow_id: self.id,
292
+ run_id:,
293
+ update_id: id,
294
+ update:,
295
+ args:,
296
+ wait_for_stage:,
297
+ headers: {},
298
+ rpc_options:
299
+ ))
300
+ end
301
+
302
+ # Send an update request to the workflow and wait for it to complete. This will target the workflow with {run_id}
303
+ # if present. To use a different run ID, create a new handle via {Client.workflow_handle}.
304
+ #
305
+ # @param update [Workflow::Definition::Update, Symbol, String] Update definition or name.
306
+ # @param args [Array<Object>] Update arguments.
307
+ # @param id [String] ID of the update.
308
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
309
+ #
310
+ # @return [Object, nil] Update result.
311
+ #
312
+ # @raise [Error::WorkflowUpdateFailedError] If the update failed.
313
+ # @raise [Error::WorkflowUpdateRPCTimeoutOrCanceledError] This update call timed out or was canceled. This doesn't
314
+ # mean the update itself was timed out or canceled.
315
+ # @raise [Error::RPCError] RPC error from call.
316
+ #
317
+ # @note Handles created as a result of {Client.start_workflow} will send updates the latest workflow with the same
318
+ # workflow ID even if it is unrelated to the started workflow.
319
+ def execute_update(update, *args, id: SecureRandom.uuid, rpc_options: nil)
320
+ start_update(
321
+ update,
322
+ *args,
323
+ wait_for_stage: WorkflowUpdateWaitStage::COMPLETED,
324
+ id:,
325
+ rpc_options:
326
+ ).result
327
+ end
328
+
329
+ # Get a handle for an update. The handle can be used to wait on the update result.
330
+ #
331
+ # @param id [String] ID of the update.
332
+ # @param specific_run_id [String, nil] Workflow run ID to get update handle for. Default is the {run_id}. Most
333
+ # users will not need to set this and instead use the one on the class.
334
+ #
335
+ # @return [WorkflowUpdateHandle] The update handle.
336
+ def update_handle(id, specific_run_id: run_id)
337
+ WorkflowUpdateHandle.new(
338
+ client: @client,
339
+ id:,
340
+ workflow_id: self.id,
341
+ workflow_run_id: specific_run_id,
342
+ known_outcome: nil
343
+ )
344
+ end
345
+
346
+ # Cancel the workflow. This will issue a cancellation for {run_id} if present. This call will make sure to use the
347
+ # run chain starting from {first_execution_run_id} if present. To create handles with these values, use
348
+ # {Client.workflow_handle}.
349
+ #
350
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
351
+ #
352
+ # @raise [Error::RPCError] RPC error from call.
353
+ #
354
+ # @note Handles created as a result of signal with start will cancel the latest workflow with the same workflow ID
355
+ # even if it is unrelated to the started workflow.
356
+ def cancel(rpc_options: nil)
357
+ @client._impl.cancel_workflow(Interceptor::CancelWorkflowInput.new(
358
+ workflow_id: id,
359
+ run_id:,
360
+ first_execution_run_id:,
361
+ rpc_options:
362
+ ))
363
+ end
364
+
365
+ # Terminate the workflow. This will issue a termination for {run_id} if present. This call will make sure to use
366
+ # the run chain starting from {first_execution_run_id} if present. To create handles with these values, use
367
+ # {Client.workflow_handle}.
368
+ #
369
+ # @param reason [String, nil] Reason for the termination.
370
+ # @param details [Array<Object>] Details to store on the termination.
371
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
372
+ #
373
+ # @raise [Error::RPCError] RPC error from call.
374
+ #
375
+ # @note Handles created as a result of signal with start will terminate the latest workflow with the same workflow
376
+ # ID even if it is unrelated to the started workflow.
377
+ def terminate(reason = nil, details: [], rpc_options: nil)
378
+ @client._impl.terminate_workflow(Interceptor::TerminateWorkflowInput.new(
379
+ workflow_id: id,
380
+ run_id:,
381
+ first_execution_run_id:,
382
+ reason:,
383
+ details:,
384
+ rpc_options:
385
+ ))
386
+ end
387
+ end
388
+ end
389
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/api'
4
+
5
+ module Temporalio
6
+ class Client
7
+ # Whether a query should be rejected in certain conditions.
8
+ module WorkflowQueryRejectCondition
9
+ NONE = Api::Enums::V1::QueryRejectCondition::QUERY_REJECT_CONDITION_NONE
10
+ NOT_OPEN = Api::Enums::V1::QueryRejectCondition::QUERY_REJECT_CONDITION_NOT_OPEN
11
+ NOT_COMPLETED_CLEANLY = Api::Enums::V1::QueryRejectCondition::QUERY_REJECT_CONDITION_NOT_COMPLETED_CLEANLY
12
+ end
13
+ end
14
+ end