temporalio 0.2.0-x86_64-linux → 0.3.0-x86_64-linux

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/Gemfile +23 -0
  4. data/Rakefile +101 -0
  5. data/lib/temporalio/activity/complete_async_error.rb +1 -1
  6. data/lib/temporalio/activity/context.rb +5 -2
  7. data/lib/temporalio/activity/definition.rb +163 -65
  8. data/lib/temporalio/activity/info.rb +22 -21
  9. data/lib/temporalio/activity.rb +2 -59
  10. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  11. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  12. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +34 -1
  13. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +1 -1
  14. data/lib/temporalio/api/cloud/identity/v1/message.rb +6 -1
  15. data/lib/temporalio/api/cloud/namespace/v1/message.rb +8 -1
  16. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  17. data/lib/temporalio/api/cloud/operation/v1/message.rb +2 -1
  18. data/lib/temporalio/api/cloud/region/v1/message.rb +2 -1
  19. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  20. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  21. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  22. data/lib/temporalio/api/common/v1/message.rb +7 -1
  23. data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
  24. data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
  25. data/lib/temporalio/api/enums/v1/reset.rb +1 -1
  26. data/lib/temporalio/api/history/v1/message.rb +1 -1
  27. data/lib/temporalio/api/nexus/v1/message.rb +2 -2
  28. data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
  29. data/lib/temporalio/api/payload_visitor.rb +1513 -0
  30. data/lib/temporalio/api/schedule/v1/message.rb +2 -1
  31. data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
  32. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  33. data/lib/temporalio/api/workflow/v1/message.rb +1 -1
  34. data/lib/temporalio/api/workflowservice/v1/request_response.rb +17 -2
  35. data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
  36. data/lib/temporalio/api.rb +1 -0
  37. data/lib/temporalio/cancellation.rb +34 -14
  38. data/lib/temporalio/client/async_activity_handle.rb +12 -37
  39. data/lib/temporalio/client/connection/cloud_service.rb +309 -231
  40. data/lib/temporalio/client/connection/operator_service.rb +36 -84
  41. data/lib/temporalio/client/connection/service.rb +6 -5
  42. data/lib/temporalio/client/connection/test_service.rb +111 -0
  43. data/lib/temporalio/client/connection/workflow_service.rb +264 -441
  44. data/lib/temporalio/client/connection.rb +90 -44
  45. data/lib/temporalio/client/interceptor.rb +160 -60
  46. data/lib/temporalio/client/schedule.rb +967 -0
  47. data/lib/temporalio/client/schedule_handle.rb +126 -0
  48. data/lib/temporalio/client/workflow_execution.rb +7 -10
  49. data/lib/temporalio/client/workflow_handle.rb +38 -95
  50. data/lib/temporalio/client/workflow_update_handle.rb +3 -5
  51. data/lib/temporalio/client.rb +122 -42
  52. data/lib/temporalio/common_enums.rb +17 -0
  53. data/lib/temporalio/converters/data_converter.rb +4 -7
  54. data/lib/temporalio/converters/failure_converter.rb +5 -3
  55. data/lib/temporalio/converters/payload_converter/composite.rb +4 -0
  56. data/lib/temporalio/converters/payload_converter.rb +6 -8
  57. data/lib/temporalio/converters/raw_value.rb +20 -0
  58. data/lib/temporalio/error/failure.rb +1 -1
  59. data/lib/temporalio/error.rb +10 -2
  60. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
  61. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  62. data/lib/temporalio/internal/bridge/{3.1 → 3.4}/temporalio_bridge.so +0 -0
  63. data/lib/temporalio/internal/bridge/api/core_interface.rb +5 -1
  64. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  65. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +5 -1
  66. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +4 -1
  67. data/lib/temporalio/internal/bridge/client.rb +11 -6
  68. data/lib/temporalio/internal/bridge/testing.rb +20 -0
  69. data/lib/temporalio/internal/bridge/worker.rb +2 -0
  70. data/lib/temporalio/internal/bridge.rb +1 -1
  71. data/lib/temporalio/internal/client/implementation.rb +245 -70
  72. data/lib/temporalio/internal/metric.rb +122 -0
  73. data/lib/temporalio/internal/proto_utils.rb +86 -7
  74. data/lib/temporalio/internal/worker/activity_worker.rb +52 -24
  75. data/lib/temporalio/internal/worker/multi_runner.rb +51 -7
  76. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  77. data/lib/temporalio/internal/worker/workflow_instance/context.rb +329 -0
  78. data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
  79. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  80. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  81. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  82. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  83. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  84. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  85. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
  86. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  87. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  88. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
  89. data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
  90. data/lib/temporalio/internal/worker/workflow_worker.rb +196 -0
  91. data/lib/temporalio/metric.rb +109 -0
  92. data/lib/temporalio/retry_policy.rb +37 -14
  93. data/lib/temporalio/runtime.rb +118 -75
  94. data/lib/temporalio/search_attributes.rb +80 -37
  95. data/lib/temporalio/testing/activity_environment.rb +2 -2
  96. data/lib/temporalio/testing/workflow_environment.rb +251 -5
  97. data/lib/temporalio/version.rb +1 -1
  98. data/lib/temporalio/worker/activity_executor/thread_pool.rb +9 -217
  99. data/lib/temporalio/worker/activity_executor.rb +3 -3
  100. data/lib/temporalio/worker/interceptor.rb +340 -66
  101. data/lib/temporalio/worker/thread_pool.rb +237 -0
  102. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
  103. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  104. data/lib/temporalio/worker.rb +201 -30
  105. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  106. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  107. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  108. data/lib/temporalio/workflow/definition.rb +566 -0
  109. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  110. data/lib/temporalio/workflow/future.rb +151 -0
  111. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  112. data/lib/temporalio/workflow/info.rb +82 -0
  113. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  114. data/lib/temporalio/workflow/update_info.rb +20 -0
  115. data/lib/temporalio/workflow.rb +523 -0
  116. data/lib/temporalio.rb +4 -0
  117. data/temporalio.gemspec +2 -2
  118. metadata +54 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8877081295dc68cb265909db90c8fee95237dd16fa4166c6ee93acbf8351382
4
- data.tar.gz: 45d18b6fce606c6890c078436933fc35062e114160a52db41d8e70d71a2e0f46
3
+ metadata.gz: '0093b1a498c767a927c15ac7bda6b07e5248ed525ebf4204b9c9d81aad7e83ce'
4
+ data.tar.gz: 962ea16d66026bb06bb23a352555c0da96e9fc119e0287747244b8eff9424e7b
5
5
  SHA512:
6
- metadata.gz: 0df865f90b92080f31577f0bc33f442a7d00226ab9fe8b73d94d20f32feb936aa9b9ef4bbaa870beb0763fa95f82a739dc8f5dbf8026acb3df622312752ebef5
7
- data.tar.gz: 851306b1152377ea05d3ae380f90949e58943dd15703a17ba16d5b2e8b2e12f4953e9d89d535ab6b2f1180947b61a8d86a4ee93dd5ebb5b04e233075cbd48706
6
+ metadata.gz: 6618dab35b06061405dafc54f82f6c4a3059ffa40b0a455aa074d56cee42da04c892262de12afa56382d4585a04ee5c49075703241964164958f487776efe462
7
+ data.tar.gz: 9adfc4bd2968b0f1a2feba6019a1f12d174aaf5aa38a161c29f83572dd322515f38e52d9db39aaa8994ff7cbb5deffbc5f35a15f5a81beb6642935f90f9b834b
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ --readme README.md
2
+ --protected
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development do
8
+ gem 'activemodel'
9
+ gem 'activerecord'
10
+ gem 'async'
11
+ gem 'base64'
12
+ gem 'grpc', '~> 1.69'
13
+ gem 'grpc-tools', '~> 1.69'
14
+ gem 'minitest'
15
+ gem 'rake'
16
+ gem 'rake-compiler'
17
+ gem 'rbs', '~> 3.5.3'
18
+ gem 'rb_sys', '~> 0.9.63'
19
+ gem 'rubocop'
20
+ gem 'sqlite3'
21
+ gem 'steep', '~> 1.7.1'
22
+ gem 'yard'
23
+ end
data/Rakefile ADDED
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Lint/MissingCopEnableDirective, Style/DocumentationMethod
4
+
5
+ require 'bundler/gem_tasks'
6
+ require 'rb_sys/cargo/metadata'
7
+ require 'rb_sys/extensiontask'
8
+
9
+ task build: :compile
10
+
11
+ GEMSPEC = Gem::Specification.load('temporalio.gemspec')
12
+
13
+ begin
14
+ RbSys::ExtensionTask.new('temporalio_bridge', GEMSPEC) do |ext|
15
+ ext.lib_dir = 'lib/temporalio/internal/bridge'
16
+ end
17
+ rescue RbSys::CargoMetadataError
18
+ raise 'Source gem cannot be installed directly, must be a supported platform'
19
+ end
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.warning = false
25
+ t.libs << 'test'
26
+ t.libs << 'lib'
27
+ t.test_files = FileList['test/**/*_test.rb']
28
+ end
29
+
30
+ def add_protoc_to_path
31
+ tools_spec = Gem::Specification.find_by_name('grpc-tools')
32
+ cpu = RbConfig::CONFIG['host_cpu']
33
+ cpu = 'x86_64' if cpu == 'x64'
34
+ os = RbConfig::CONFIG['host_os']
35
+ os = 'windows' if os.start_with?('mingw')
36
+ protoc_path = "#{tools_spec.gem_dir}/bin/#{cpu}-#{os}"
37
+ separator = os == 'windows' ? ';' : ':'
38
+ ENV['PATH'] = "#{ENV.fetch('PATH', nil)}#{separator}#{protoc_path}"
39
+ end
40
+
41
+ add_protoc_to_path
42
+
43
+ require 'rubocop/rake_task'
44
+
45
+ RuboCop::RakeTask.new
46
+
47
+ require 'steep/rake_task'
48
+
49
+ Steep::RakeTask.new
50
+
51
+ require 'yard'
52
+
53
+ module CustomizeYardWarnings # rubocop:disable Style/Documentation
54
+ def process
55
+ super
56
+ rescue YARD::Parser::UndocumentableError
57
+ # We ignore if it's an API warning
58
+ last_file = statement.last.file
59
+ raise unless (last_file.start_with?('lib/temporalio/api/') && last_file.count('/') > 3) ||
60
+ last_file.start_with?('lib/temporalio/internal/bridge/api/')
61
+ end
62
+ end
63
+
64
+ YARD::Handlers::Ruby::ConstantHandler.prepend(CustomizeYardWarnings)
65
+
66
+ YARD::Rake::YardocTask.new { |t| t.options = ['--fail-on-warning'] }
67
+
68
+ Rake::Task[:yard].enhance([:copy_parent_files]) do
69
+ rm ['LICENSE', 'README.md']
70
+ end
71
+
72
+ namespace :proto do
73
+ desc 'Generate API and Core protobufs'
74
+ task :generate do
75
+ require_relative 'extra/proto_gen'
76
+ ProtoGen.new.run
77
+ end
78
+ end
79
+
80
+ namespace :rbs do
81
+ desc 'RBS tasks'
82
+ task :install_collection do
83
+ sh 'rbs collection install'
84
+ end
85
+ end
86
+
87
+ # We have to copy some parent files to this dir for gem
88
+ task :copy_parent_files do
89
+ cp '../LICENSE', 'LICENSE'
90
+ cp '../README.md', 'README.md'
91
+ end
92
+ Rake::Task[:build].enhance([:copy_parent_files]) do
93
+ rm ['LICENSE', 'README.md']
94
+ end
95
+
96
+ task :rust_lint do
97
+ sh 'cargo', 'clippy', '--', '-Dwarnings'
98
+ sh 'cargo', 'fmt', '--check'
99
+ end
100
+
101
+ task default: ['rubocop', 'yard', 'rbs:install_collection', 'steep', 'rust_lint', 'compile', 'test']
@@ -3,7 +3,7 @@
3
3
  require 'temporalio/error'
4
4
 
5
5
  module Temporalio
6
- class Activity
6
+ module Activity
7
7
  # Error raised inside an activity to mark that the activity will be completed asynchronously.
8
8
  class CompleteAsyncError < Error
9
9
  end
@@ -3,7 +3,7 @@
3
3
  require 'temporalio/error'
4
4
 
5
5
  module Temporalio
6
- class Activity
6
+ module Activity
7
7
  # Context accessible only within an activity. Use {current} to get the current context. Contexts are fiber or thread
8
8
  # local so may not be available in a newly started thread from an activity and may have to be propagated manually.
9
9
  class Context
@@ -101,7 +101,10 @@ module Temporalio
101
101
  }.freeze
102
102
  end
103
103
 
104
- # TODO(cretz): metric meter
104
+ # @return [Metric::Meter] Metric meter to create metrics on, with some activity-specific attributes already set.
105
+ def metric_meter
106
+ raise NotImplementedError
107
+ end
105
108
  end
106
109
  end
107
110
  end
@@ -1,76 +1,174 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Temporalio
4
- class Activity
5
- # Definition of an activity. Activities are usually classes/instances that extend {Activity}, but definitions can
6
- # also be manually created with a proc/block.
4
+ module Activity
5
+ # Base class for all activities.
6
+ #
7
+ # Activities can be given to a worker as instances of this class, which will call execute on the same instance for
8
+ # each execution, or given to the worker as the class itself which instantiates the activity for each execution.
9
+ #
10
+ # All activities must implement {execute}. Inside execute, {Activity::Context.current} can be used to access the
11
+ # current context to get information, issue heartbeats, etc.
12
+ #
13
+ # By default, the activity is named as its unqualified class name. This can be customized with {activity_name}.
14
+ #
15
+ # By default, the activity uses the `:default` executor which is usually the thread-pool based executor. This can be
16
+ # customized with {activity_executor}.
17
+ #
18
+ # By default, upon cancellation {::Thread.raise} or {::Fiber.raise} is called with a {Error::CanceledError}. This
19
+ # can be disabled by passing `false` to {activity_cancel_raise}.
20
+ #
21
+ # See documentation for more detail on activities.
7
22
  class Definition
8
- # @return [String, Symbol] Name of the activity.
9
- attr_reader :name
10
-
11
- # @return [Proc] Proc for the activity.
12
- attr_reader :proc
13
-
14
- # @return [Symbol] Name of the executor. Default is `:default`.
15
- attr_reader :executor
16
-
17
- # @return [Boolean] Whether to raise in thread/fiber on cancellation. Default is `true`.
18
- attr_reader :cancel_raise
19
-
20
- # Obtain a definition representing the given activity, which can be a class, instance, or definition.
21
- #
22
- # @param activity [Activity, Class<Activity>, Definition] Activity to get definition for.
23
- # @return Definition Obtained definition.
24
- def self.from_activity(activity)
25
- # Class means create each time, instance means just call, definition
26
- # does nothing special
27
- case activity
28
- when Class
29
- raise ArgumentError, "Class '#{activity}' does not extend Activity" unless activity < Activity
30
-
31
- details = activity._activity_definition_details
32
- new(
33
- name: details[:activity_name],
34
- executor: details[:activity_executor],
35
- cancel_raise: details[:activity_cancel_raise],
36
- # Instantiate and call
37
- proc: proc { |*args| activity.new.execute(*args) }
38
- )
39
- when Activity
40
- details = activity.class._activity_definition_details
41
- new(
42
- name: details[:activity_name],
43
- executor: details[:activity_executor],
44
- cancel_raise: details[:activity_cancel_raise],
45
- # Just call
46
- proc: proc { |*args| activity.execute(*args) }
47
- )
48
- when Activity::Definition
49
- activity
50
- else
51
- raise ArgumentError, "#{activity} is not an activity class, instance, or definition"
23
+ class << self
24
+ protected
25
+
26
+ # Override the activity name which is defaulted to the unqualified class name.
27
+ #
28
+ # @param name [String, Symbol] Name to use.
29
+ def activity_name(name)
30
+ if !name.is_a?(Symbol) && !name.is_a?(String)
31
+ raise ArgumentError,
32
+ 'Activity name must be a symbol or string'
33
+ end
34
+
35
+ @activity_name = name.to_s
36
+ end
37
+
38
+ # Override the activity executor which is defaulted to `:default`.
39
+ #
40
+ # @param executor_name [Symbol] Executor to use.
41
+ def activity_executor(executor_name)
42
+ raise ArgumentError, 'Executor name must be a symbol' unless executor_name.is_a?(Symbol)
43
+
44
+ @activity_executor = executor_name
45
+ end
46
+
47
+ # Override whether the activity uses Thread/Fiber raise for cancellation which is defaulted to true.
48
+ #
49
+ # @param cancel_raise [Boolean] Whether to raise.
50
+ def activity_cancel_raise(cancel_raise)
51
+ unless cancel_raise.is_a?(TrueClass) || cancel_raise.is_a?(FalseClass)
52
+ raise ArgumentError, 'Must be a boolean'
53
+ end
54
+
55
+ @activity_cancel_raise = cancel_raise
56
+ end
57
+
58
+ # Set an activity as dynamic. Dynamic activities do not have names and handle any activity that is not otherwise
59
+ # registered. A worker can only have one dynamic activity. It is often useful to use {activity_raw_args} with
60
+ # this.
61
+ #
62
+ # @param value [Boolean] Whether the activity is dynamic.
63
+ def activity_dynamic(value = true) # rubocop:disable Style/OptionalBooleanParameter
64
+ raise ArgumentError, 'Must be a boolean' unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
65
+
66
+ @activity_dynamic = value
67
+ end
68
+
69
+ # Have activity arguments delivered to `execute` as {Converters::RawValue}s. These are wrappers for the raw
70
+ # payloads that have not been converted to types (but they have been decoded by the codec if present). They can
71
+ # be converted with {Context#payload_converter}.
72
+ #
73
+ # @param value [Boolean] Whether the activity accepts raw arguments.
74
+ def activity_raw_args(value = true) # rubocop:disable Style/OptionalBooleanParameter
75
+ raise ArgumentError, 'Must be a boolean' unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
76
+
77
+ @activity_raw_args = value
52
78
  end
53
79
  end
54
80
 
55
- # Manually create activity definition. Most users will use an instance/class of {Activity}.
56
- #
57
- # @param name [String, Symbol] Name of the activity.
58
- # @param proc [Proc, nil] Proc for the activity, or can give block.
59
- # @param executor [Symbol] Name of the executor.
60
- # @param cancel_raise [Boolean] Whether to raise in thread/fiber on cancellation.
61
- # @yield Use this block as the activity. Cannot be present with `proc`.
62
- def initialize(name:, proc: nil, executor: :default, cancel_raise: true, &block)
63
- @name = name
64
- if proc.nil?
65
- raise ArgumentError, 'Must give proc or block' unless block_given?
66
-
67
- proc = block
68
- elsif block_given?
69
- raise ArgumentError, 'Cannot give proc and block'
81
+ # @!visibility private
82
+ def self._activity_definition_details
83
+ activity_name = @activity_name
84
+ raise 'Cannot have activity name specified for dynamic activity' if activity_name && @activity_dynamic
85
+
86
+ # Default to unqualified class name if not dynamic
87
+ activity_name ||= name.to_s.split('::').last unless @activity_dynamic
88
+ {
89
+ activity_name:,
90
+ activity_executor: @activity_executor || :default,
91
+ activity_cancel_raise: @activity_cancel_raise.nil? ? true : @activity_cancel_raise,
92
+ activity_raw_args: @activity_raw_args.nil? ? false : @activity_raw_args
93
+ }
94
+ end
95
+
96
+ # Implementation of the activity. The arguments should be positional and this should return the value on success
97
+ # or raise an error on failure.
98
+ def execute(*args)
99
+ raise NotImplementedError, 'Activity did not implement "execute"'
100
+ end
101
+
102
+ # Definition info of an activity. Activities are usually classes/instances that extend {Definition}, but
103
+ # definitions can also be manually created with a block via {initialize} here.
104
+ class Info
105
+ # @return [String, Symbol, nil] Name of the activity, or nil if the activity is dynamic.
106
+ attr_reader :name
107
+
108
+ # @return [Proc] Proc for the activity.
109
+ attr_reader :proc
110
+
111
+ # @return [Symbol] Name of the executor. Default is `:default`.
112
+ attr_reader :executor
113
+
114
+ # @return [Boolean] Whether to raise in thread/fiber on cancellation. Default is `true`.
115
+ attr_reader :cancel_raise
116
+
117
+ # @return [Boolean] Whether to use {Converters::RawValue}s as arguments.
118
+ attr_reader :raw_args
119
+
120
+ # Obtain definition info representing the given activity, which can be a class, instance, or definition info.
121
+ #
122
+ # @param activity [Definition, Class<Definition>, Info] Activity to get info for.
123
+ # @return Info Obtained definition info.
124
+ def self.from_activity(activity)
125
+ # Class means create each time, instance means just call, definition
126
+ # does nothing special
127
+ case activity
128
+ when Class
129
+ unless activity < Definition
130
+ raise ArgumentError,
131
+ "Class '#{activity}' does not extend Temporalio::Activity::Definition"
132
+ end
133
+
134
+ details = activity._activity_definition_details
135
+ new(
136
+ name: details[:activity_name],
137
+ executor: details[:activity_executor],
138
+ cancel_raise: details[:activity_cancel_raise],
139
+ raw_args: details[:activity_raw_args]
140
+ ) { |*args| activity.new.execute(*args) } # Instantiate and call
141
+ when Definition
142
+ details = activity.class._activity_definition_details
143
+ new(
144
+ name: details[:activity_name],
145
+ executor: details[:activity_executor],
146
+ cancel_raise: details[:activity_cancel_raise],
147
+ raw_args: details[:activity_raw_args]
148
+ ) { |*args| activity.execute(*args) } # Just and call
149
+ when Info
150
+ activity
151
+ else
152
+ raise ArgumentError, "#{activity} is not an activity class, instance, or definition info"
153
+ end
154
+ end
155
+
156
+ # Manually create activity definition info. Most users will use an instance/class of {Definition}.
157
+ #
158
+ # @param name [String, Symbol, nil] Name of the activity or nil for dynamic activity.
159
+ # @param executor [Symbol] Name of the executor.
160
+ # @param cancel_raise [Boolean] Whether to raise in thread/fiber on cancellation.
161
+ # @param raw_args [Boolean] Whether to use {Converters::RawValue}s as arguments.
162
+ # @yield Use this block as the activity.
163
+ def initialize(name:, executor: :default, cancel_raise: true, raw_args: false, &block)
164
+ @name = name
165
+ raise ArgumentError, 'Must give block' unless block_given?
166
+
167
+ @proc = block
168
+ @executor = executor
169
+ @cancel_raise = cancel_raise
170
+ @raw_args = raw_args
70
171
  end
71
- @proc = proc
72
- @executor = executor
73
- @cancel_raise = cancel_raise
74
172
  end
75
173
  end
76
174
  end
@@ -1,7 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Temporalio
4
- class Activity
4
+ module Activity
5
+ Info = Data.define(
6
+ :activity_id,
7
+ :activity_type,
8
+ :attempt,
9
+ :current_attempt_scheduled_time,
10
+ :heartbeat_details,
11
+ :heartbeat_timeout,
12
+ :local?,
13
+ :schedule_to_close_timeout,
14
+ :scheduled_time,
15
+ :start_to_close_timeout,
16
+ :started_time,
17
+ :task_queue,
18
+ :task_token,
19
+ :workflow_id,
20
+ :workflow_namespace,
21
+ :workflow_run_id,
22
+ :workflow_type
23
+ )
24
+
5
25
  # Information about an activity.
6
26
  #
7
27
  # @!attribute activity_id
@@ -39,25 +59,6 @@ module Temporalio
39
59
  # @return [String] Workflow run ID that started this activity.
40
60
  # @!attribute workflow_type
41
61
  # @return [String] Workflow type name that started this activity.
42
- Info = Struct.new(
43
- :activity_id,
44
- :activity_type,
45
- :attempt,
46
- :current_attempt_scheduled_time,
47
- :heartbeat_details,
48
- :heartbeat_timeout,
49
- :local?,
50
- :schedule_to_close_timeout,
51
- :scheduled_time,
52
- :start_to_close_timeout,
53
- :started_time,
54
- :task_queue,
55
- :task_token,
56
- :workflow_id,
57
- :workflow_namespace,
58
- :workflow_run_id,
59
- :workflow_type,
60
- keyword_init: true
61
- )
62
+ class Info; end # rubocop:disable Lint/EmptyClass
62
63
  end
63
64
  end
@@ -6,64 +6,7 @@ require 'temporalio/activity/definition'
6
6
  require 'temporalio/activity/info'
7
7
 
8
8
  module Temporalio
9
- # Base class for all activities.
10
- #
11
- # Activities can be given to a worker as instances of this class, which will call execute on the same instance for
12
- # each execution, or given to the worker as the class itself which instantiates the activity for each execution.
13
- #
14
- # All activities must implement {execute}. Inside execute, {Activity::Context.current} can be used to access the
15
- # current context to get information, issue heartbeats, etc.
16
- #
17
- # By default, the activity is named as its unqualified class name. This can be customized with {activity_name}.
18
- #
19
- # By default, the activity uses the `:default` executor which is usually the thread-pool based executor. This can be
20
- # customized with {activity_executor}.
21
- #
22
- # By default, upon cancellation {::Thread.raise} or {::Fiber.raise} is called with a {Error::CanceledError}. This can
23
- # be disabled by passing `false` to {activity_cancel_raise}.
24
- #
25
- # See documentation for more detail on activities.
26
- class Activity
27
- # Override the activity name which is defaulted to the unqualified class name.
28
- #
29
- # @param name [String, Symbol] Name to use.
30
- def self.activity_name(name)
31
- raise ArgumentError, 'Activity name must be a symbol or string' if !name.is_a?(Symbol) && !name.is_a?(String)
32
-
33
- @activity_name = name.to_s
34
- end
35
-
36
- # Override the activity executor which is defaulted to `:default`.
37
- #
38
- # @param executor_name [Symbol] Executor to use.
39
- def self.activity_executor(executor_name)
40
- raise ArgumentError, 'Executor name must be a symbol' unless executor_name.is_a?(Symbol)
41
-
42
- @activity_executor = executor_name
43
- end
44
-
45
- # Override whether the activity uses Thread/Fiber raise for cancellation which is defaulted to true.
46
- #
47
- # @param cancel_raise [Boolean] Whether to raise.
48
- def self.activity_cancel_raise(cancel_raise)
49
- raise ArgumentError, 'Must be a boolean' unless cancel_raise.is_a?(TrueClass) || cancel_raise.is_a?(FalseClass)
50
-
51
- @activity_cancel_raise = cancel_raise
52
- end
53
-
54
- # @!visibility private
55
- def self._activity_definition_details
56
- {
57
- activity_name: @activity_name || name.to_s.split('::').last,
58
- activity_executor: @activity_executor || :default,
59
- activity_cancel_raise: @activity_cancel_raise.nil? ? true : @activity_cancel_raise
60
- }
61
- end
62
-
63
- # Implementation of the activity. The arguments should be positional and this should return the value on success or
64
- # raise an error on failure.
65
- def execute(*args)
66
- raise NotImplementedError, 'Activity did not implement "execute"'
67
- end
9
+ # All activity related classes.
10
+ module Activity
68
11
  end
69
12
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: temporal/api/activity/v1/message.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+ require 'temporalio/api/common/v1/message'
8
+ require 'temporalio/api/taskqueue/v1/message'
9
+ require 'google/protobuf/duration_pb'
10
+
11
+
12
+ descriptor_data = "\n&temporal/api/activity/v1/message.proto\x12\x18temporal.api.activity.v1\x1a$temporal/api/common/v1/message.proto\x1a\'temporal/api/taskqueue/v1/message.proto\x1a\x1egoogle/protobuf/duration.proto\"\xf3\x02\n\x0f\x41\x63tivityOptions\x12\x38\n\ntask_queue\x18\x01 \x01(\x0b\x32$.temporal.api.taskqueue.v1.TaskQueue\x12<\n\x19schedule_to_close_timeout\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\x06 \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicyB\x93\x01\n\x1bio.temporal.api.activity.v1B\x0cMessageProtoP\x01Z\'go.temporal.io/api/activity/v1;activity\xaa\x02\x1aTemporalio.Api.Activity.V1\xea\x02\x1dTemporalio::Api::Activity::V1b\x06proto3"
13
+
14
+ pool = Google::Protobuf::DescriptorPool.generated_pool
15
+ pool.add_serialized_file(descriptor_data)
16
+
17
+ module Temporalio
18
+ module Api
19
+ module Activity
20
+ module V1
21
+ ActivityOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("temporal.api.activity.v1.ActivityOptions").msgclass
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: temporal/api/cloud/account/v1/message.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+ require 'temporalio/api/cloud/resource/v1/message'
8
+
9
+
10
+ descriptor_data = "\n+temporal/api/cloud/account/v1/message.proto\x12\x1dtemporal.api.cloud.account.v1\x1a,temporal/api/cloud/resource/v1/message.proto\")\n\x0bMetricsSpec\x12\x1a\n\x12\x61\x63\x63\x65pted_client_ca\x18\x02 \x01(\x0c\"J\n\x0b\x41\x63\x63ountSpec\x12;\n\x07metrics\x18\x01 \x01(\x0b\x32*.temporal.api.cloud.account.v1.MetricsSpec\"\x16\n\x07Metrics\x12\x0b\n\x03uri\x18\x01 \x01(\t\"\xfc\x01\n\x07\x41\x63\x63ount\x12\n\n\x02id\x18\x01 \x01(\t\x12\x38\n\x04spec\x18\x02 \x01(\x0b\x32*.temporal.api.cloud.account.v1.AccountSpec\x12\x18\n\x10resource_version\x18\x03 \x01(\t\x12<\n\x05state\x18\x04 \x01(\x0e\x32-.temporal.api.cloud.resource.v1.ResourceState\x12\x1a\n\x12\x61sync_operation_id\x18\x05 \x01(\t\x12\x37\n\x07metrics\x18\x06 \x01(\x0b\x32&.temporal.api.cloud.account.v1.MetricsB\xa7\x01\n io.temporal.api.cloud.account.v1B\x0cMessageProtoP\x01Z+go.temporal.io/api/cloud/account/v1;account\xaa\x02\x1fTemporalio.Api.Cloud.Account.V1\xea\x02#Temporalio::Api::Cloud::Account::V1b\x06proto3"
11
+
12
+ pool = Google::Protobuf::DescriptorPool.generated_pool
13
+ pool.add_serialized_file(descriptor_data)
14
+
15
+ module Temporalio
16
+ module Api
17
+ module Cloud
18
+ module Account
19
+ module V1
20
+ MetricsSpec = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("temporal.api.cloud.account.v1.MetricsSpec").msgclass
21
+ AccountSpec = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("temporal.api.cloud.account.v1.AccountSpec").msgclass
22
+ Metrics = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("temporal.api.cloud.account.v1.Metrics").msgclass
23
+ Account = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("temporal.api.cloud.account.v1.Account").msgclass
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end