temporalio 0.2.0-x86_64-darwin → 0.4.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.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/Gemfile +7 -3
- data/Rakefile +10 -296
- data/lib/temporalio/activity/complete_async_error.rb +1 -1
- data/lib/temporalio/activity/context.rb +18 -2
- data/lib/temporalio/activity/definition.rb +180 -65
- data/lib/temporalio/activity/info.rb +25 -21
- data/lib/temporalio/activity.rb +2 -59
- data/lib/temporalio/api/activity/v1/message.rb +25 -0
- data/lib/temporalio/api/batch/v1/message.rb +6 -1
- data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
- data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +34 -1
- data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +1 -1
- data/lib/temporalio/api/cloud/identity/v1/message.rb +6 -1
- data/lib/temporalio/api/cloud/namespace/v1/message.rb +8 -1
- data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
- data/lib/temporalio/api/cloud/operation/v1/message.rb +2 -1
- data/lib/temporalio/api/cloud/region/v1/message.rb +2 -1
- data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
- data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
- data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
- data/lib/temporalio/api/command/v1/message.rb +1 -1
- data/lib/temporalio/api/common/v1/message.rb +8 -1
- data/lib/temporalio/api/deployment/v1/message.rb +38 -0
- data/lib/temporalio/api/enums/v1/batch_operation.rb +1 -1
- data/lib/temporalio/api/enums/v1/common.rb +1 -1
- data/lib/temporalio/api/enums/v1/deployment.rb +23 -0
- data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
- data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
- data/lib/temporalio/api/enums/v1/nexus.rb +21 -0
- data/lib/temporalio/api/enums/v1/reset.rb +1 -1
- data/lib/temporalio/api/enums/v1/workflow.rb +2 -1
- data/lib/temporalio/api/errordetails/v1/message.rb +3 -1
- data/lib/temporalio/api/failure/v1/message.rb +3 -1
- data/lib/temporalio/api/history/v1/message.rb +3 -1
- data/lib/temporalio/api/nexus/v1/message.rb +3 -2
- data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
- data/lib/temporalio/api/payload_visitor.rb +1581 -0
- data/lib/temporalio/api/query/v1/message.rb +2 -1
- data/lib/temporalio/api/schedule/v1/message.rb +2 -1
- data/lib/temporalio/api/taskqueue/v1/message.rb +4 -1
- data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
- data/lib/temporalio/api/testservice/v1/service.rb +23 -0
- data/lib/temporalio/api/workflow/v1/message.rb +9 -1
- data/lib/temporalio/api/workflowservice/v1/request_response.rb +46 -2
- data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
- data/lib/temporalio/api.rb +2 -0
- data/lib/temporalio/cancellation.rb +34 -14
- data/lib/temporalio/client/async_activity_handle.rb +12 -37
- data/lib/temporalio/client/connection/cloud_service.rb +309 -231
- data/lib/temporalio/client/connection/operator_service.rb +36 -84
- data/lib/temporalio/client/connection/service.rb +6 -5
- data/lib/temporalio/client/connection/test_service.rb +111 -0
- data/lib/temporalio/client/connection/workflow_service.rb +474 -441
- data/lib/temporalio/client/connection.rb +90 -44
- data/lib/temporalio/client/interceptor.rb +199 -60
- data/lib/temporalio/client/schedule.rb +991 -0
- data/lib/temporalio/client/schedule_handle.rb +126 -0
- data/lib/temporalio/client/with_start_workflow_operation.rb +115 -0
- data/lib/temporalio/client/workflow_execution.rb +26 -10
- data/lib/temporalio/client/workflow_handle.rb +41 -98
- data/lib/temporalio/client/workflow_update_handle.rb +3 -5
- data/lib/temporalio/client.rb +247 -44
- data/lib/temporalio/common_enums.rb +17 -0
- data/lib/temporalio/contrib/open_telemetry.rb +470 -0
- data/lib/temporalio/converters/data_converter.rb +4 -7
- data/lib/temporalio/converters/failure_converter.rb +5 -3
- data/lib/temporalio/converters/payload_converter/composite.rb +4 -0
- data/lib/temporalio/converters/payload_converter.rb +6 -8
- data/lib/temporalio/converters/raw_value.rb +20 -0
- data/lib/temporalio/error/failure.rb +1 -1
- data/lib/temporalio/error.rb +11 -2
- data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.bundle +0 -0
- data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.bundle +0 -0
- data/lib/temporalio/internal/bridge/{3.1 → 3.4}/temporalio_bridge.bundle +0 -0
- data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +1 -1
- data/lib/temporalio/internal/bridge/api/common/common.rb +2 -1
- data/lib/temporalio/internal/bridge/api/core_interface.rb +5 -1
- data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
- data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +5 -1
- data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +4 -1
- data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +2 -1
- data/lib/temporalio/internal/bridge/client.rb +11 -6
- data/lib/temporalio/internal/bridge/runtime.rb +3 -0
- data/lib/temporalio/internal/bridge/testing.rb +23 -0
- data/lib/temporalio/internal/bridge/worker.rb +2 -0
- data/lib/temporalio/internal/bridge.rb +1 -1
- data/lib/temporalio/internal/client/implementation.rb +468 -71
- data/lib/temporalio/internal/metric.rb +122 -0
- data/lib/temporalio/internal/proto_utils.rb +118 -7
- data/lib/temporalio/internal/worker/activity_worker.rb +69 -29
- data/lib/temporalio/internal/worker/multi_runner.rb +53 -9
- data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
- data/lib/temporalio/internal/worker/workflow_instance/context.rb +383 -0
- data/lib/temporalio/internal/worker/workflow_instance/details.rb +46 -0
- data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
- data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
- data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
- data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
- data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
- data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
- data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +400 -0
- data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
- data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
- data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +183 -0
- data/lib/temporalio/internal/worker/workflow_instance.rb +774 -0
- data/lib/temporalio/internal/worker/workflow_worker.rb +239 -0
- data/lib/temporalio/metric.rb +109 -0
- data/lib/temporalio/retry_policy.rb +37 -14
- data/lib/temporalio/runtime/metric_buffer.rb +94 -0
- data/lib/temporalio/runtime.rb +160 -79
- data/lib/temporalio/search_attributes.rb +93 -37
- data/lib/temporalio/testing/activity_environment.rb +44 -16
- data/lib/temporalio/testing/workflow_environment.rb +276 -7
- data/lib/temporalio/version.rb +1 -1
- data/lib/temporalio/worker/activity_executor/thread_pool.rb +9 -217
- data/lib/temporalio/worker/activity_executor.rb +3 -3
- data/lib/temporalio/worker/interceptor.rb +343 -66
- data/lib/temporalio/worker/thread_pool.rb +237 -0
- data/lib/temporalio/worker/tuner.rb +38 -0
- data/lib/temporalio/worker/workflow_executor/thread_pool.rb +235 -0
- data/lib/temporalio/worker/workflow_executor.rb +26 -0
- data/lib/temporalio/worker/workflow_replayer.rb +350 -0
- data/lib/temporalio/worker.rb +235 -58
- data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
- data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
- data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
- data/lib/temporalio/workflow/definition.rb +598 -0
- data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
- data/lib/temporalio/workflow/future.rb +151 -0
- data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
- data/lib/temporalio/workflow/info.rb +104 -0
- data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
- data/lib/temporalio/workflow/update_info.rb +20 -0
- data/lib/temporalio/workflow.rb +575 -0
- data/lib/temporalio/workflow_history.rb +26 -1
- data/lib/temporalio.rb +4 -0
- data/temporalio.gemspec +4 -3
- metadata +75 -8
| @@ -0,0 +1,122 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'singleton'
         | 
| 4 | 
            +
            require 'temporalio/internal/bridge'
         | 
| 5 | 
            +
            require 'temporalio/metric'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Temporalio
         | 
| 8 | 
            +
              module Internal
         | 
| 9 | 
            +
                class Metric < Temporalio::Metric
         | 
| 10 | 
            +
                  attr_reader :metric_type, :name, :description, :unit, :value_type
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  def initialize(metric_type:, name:, description:, unit:, value_type:, bridge:, bridge_attrs:) # rubocop:disable Lint/MissingSuper
         | 
| 13 | 
            +
                    @metric_type = metric_type
         | 
| 14 | 
            +
                    @name = name
         | 
| 15 | 
            +
                    @description = description
         | 
| 16 | 
            +
                    @unit = unit
         | 
| 17 | 
            +
                    @value_type = value_type
         | 
| 18 | 
            +
                    @bridge = bridge
         | 
| 19 | 
            +
                    @bridge_attrs = bridge_attrs
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def record(value, additional_attributes: nil)
         | 
| 23 | 
            +
                    bridge_attrs = @bridge_attrs
         | 
| 24 | 
            +
                    bridge_attrs = @bridge_attrs.with_additional(additional_attributes) if additional_attributes
         | 
| 25 | 
            +
                    @bridge.record_value(value, bridge_attrs)
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def with_additional_attributes(additional_attributes)
         | 
| 29 | 
            +
                    Metric.new(
         | 
| 30 | 
            +
                      metric_type:,
         | 
| 31 | 
            +
                      name:,
         | 
| 32 | 
            +
                      description:,
         | 
| 33 | 
            +
                      unit:,
         | 
| 34 | 
            +
                      value_type:,
         | 
| 35 | 
            +
                      bridge: @bridge,
         | 
| 36 | 
            +
                      bridge_attrs: @bridge_attrs.with_additional(additional_attributes)
         | 
| 37 | 
            +
                    )
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  class Meter < Temporalio::Metric::Meter
         | 
| 41 | 
            +
                    def self.create_from_runtime(runtime)
         | 
| 42 | 
            +
                      bridge = Bridge::Metric::Meter.new(runtime._core_runtime)
         | 
| 43 | 
            +
                      return nil unless bridge
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      Meter.new(bridge, bridge.default_attributes)
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                    def initialize(bridge, bridge_attrs) # rubocop:disable Lint/MissingSuper
         | 
| 49 | 
            +
                      @bridge = bridge
         | 
| 50 | 
            +
                      @bridge_attrs = bridge_attrs
         | 
| 51 | 
            +
                    end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    def create_metric(
         | 
| 54 | 
            +
                      metric_type,
         | 
| 55 | 
            +
                      name,
         | 
| 56 | 
            +
                      description: nil,
         | 
| 57 | 
            +
                      unit: nil,
         | 
| 58 | 
            +
                      value_type: :integer
         | 
| 59 | 
            +
                    )
         | 
| 60 | 
            +
                      Metric.new(
         | 
| 61 | 
            +
                        metric_type:,
         | 
| 62 | 
            +
                        name:,
         | 
| 63 | 
            +
                        description:,
         | 
| 64 | 
            +
                        unit:,
         | 
| 65 | 
            +
                        value_type:,
         | 
| 66 | 
            +
                        bridge: Bridge::Metric.new(@bridge, metric_type, name, description, unit, value_type),
         | 
| 67 | 
            +
                        bridge_attrs: @bridge_attrs
         | 
| 68 | 
            +
                      )
         | 
| 69 | 
            +
                    end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    def with_additional_attributes(additional_attributes)
         | 
| 72 | 
            +
                      Meter.new(@bridge, @bridge_attrs.with_additional(additional_attributes))
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  class NullMeter < Temporalio::Metric::Meter
         | 
| 77 | 
            +
                    include Singleton
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    def initialize # rubocop:disable Style/RedundantInitialize,Lint/MissingSuper
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    def create_metric(
         | 
| 83 | 
            +
                      metric_type,
         | 
| 84 | 
            +
                      name,
         | 
| 85 | 
            +
                      description: nil,
         | 
| 86 | 
            +
                      unit: nil,
         | 
| 87 | 
            +
                      value_type: :integer
         | 
| 88 | 
            +
                    )
         | 
| 89 | 
            +
                      NullMetric.new(
         | 
| 90 | 
            +
                        metric_type:,
         | 
| 91 | 
            +
                        name:,
         | 
| 92 | 
            +
                        description:,
         | 
| 93 | 
            +
                        unit:,
         | 
| 94 | 
            +
                        value_type:
         | 
| 95 | 
            +
                      )
         | 
| 96 | 
            +
                    end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    def with_additional_attributes(_additional_attributes)
         | 
| 99 | 
            +
                      self
         | 
| 100 | 
            +
                    end
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  class NullMetric < Temporalio::Metric
         | 
| 104 | 
            +
                    attr_reader :metric_type, :name, :description, :unit, :value_type
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    def initialize(metric_type:, name:, description:, unit:, value_type:) # rubocop:disable Lint/MissingSuper
         | 
| 107 | 
            +
                      @metric_type = metric_type
         | 
| 108 | 
            +
                      @name = name
         | 
| 109 | 
            +
                      @description = description
         | 
| 110 | 
            +
                      @unit = unit
         | 
| 111 | 
            +
                      @value_type = value_type
         | 
| 112 | 
            +
                    end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                    def record(value, additional_attributes: nil); end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    def with_additional_attributes(_additional_attributes)
         | 
| 117 | 
            +
                      self
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
            end
         | 
| @@ -5,26 +5,82 @@ require 'temporalio/api' | |
| 5 5 | 
             
            module Temporalio
         | 
| 6 6 | 
             
              module Internal
         | 
| 7 7 | 
             
                module ProtoUtils
         | 
| 8 | 
            -
                  def self.seconds_to_duration( | 
| 9 | 
            -
                    return nil if  | 
| 8 | 
            +
                  def self.seconds_to_duration(seconds_numeric)
         | 
| 9 | 
            +
                    return nil if seconds_numeric.nil?
         | 
| 10 10 |  | 
| 11 | 
            -
                    seconds =  | 
| 12 | 
            -
                    nanos = (( | 
| 11 | 
            +
                    seconds = seconds_numeric.to_i
         | 
| 12 | 
            +
                    nanos = ((seconds_numeric - seconds) * 1_000_000_000).round
         | 
| 13 13 | 
             
                    Google::Protobuf::Duration.new(seconds:, nanos:)
         | 
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 | 
            +
                  def self.duration_to_seconds(duration)
         | 
| 17 | 
            +
                    return nil if duration.nil?
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    # This logic was corrected for timestamp at
         | 
| 20 | 
            +
                    # https://github.com/protocolbuffers/protobuf/pull/2482 but not for
         | 
| 21 | 
            +
                    # duration, so 4.56 is not properly represented in to_f, it becomes
         | 
| 22 | 
            +
                    # 4.5600000000000005.
         | 
| 23 | 
            +
                    (duration.seconds + duration.nanos.quo(1_000_000_000)).to_f
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def self.time_to_timestamp(time)
         | 
| 27 | 
            +
                    return nil if time.nil?
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    Google::Protobuf::Timestamp.from_time(time)
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def self.timestamp_to_time(timestamp)
         | 
| 33 | 
            +
                    return nil if timestamp.nil?
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    # The regular to_time on the timestamp converts to local timezone,
         | 
| 36 | 
            +
                    # and we prefer not to make a separate .utc call (converts to local
         | 
| 37 | 
            +
                    # then back to UTC unnecessarily)
         | 
| 38 | 
            +
                    Time.at(timestamp.seconds, timestamp.nanos, :nanosecond, in: 'UTC')
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 16 41 | 
             
                  def self.memo_to_proto(hash, converter)
         | 
| 17 | 
            -
                    return nil if hash.nil?
         | 
| 42 | 
            +
                    return nil if hash.nil? || hash.empty?
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    Api::Common::V1::Memo.new(fields: memo_to_proto_hash(hash, converter))
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def self.memo_to_proto_hash(hash, converter)
         | 
| 48 | 
            +
                    return nil if hash.nil? || hash.empty?
         | 
| 18 49 |  | 
| 19 | 
            -
                     | 
| 50 | 
            +
                    hash.transform_keys(&:to_s).transform_values { |val| converter.to_payload(val) }
         | 
| 20 51 | 
             
                  end
         | 
| 21 52 |  | 
| 22 53 | 
             
                  def self.memo_from_proto(memo, converter)
         | 
| 23 | 
            -
                    return nil if memo.nil?
         | 
| 54 | 
            +
                    return nil if memo.nil? || memo.fields.size.zero? # rubocop:disable Style/ZeroLengthPredicate -- Google Maps don't have empty
         | 
| 24 55 |  | 
| 25 56 | 
             
                    memo.fields.each_with_object({}) { |(key, val), h| h[key] = converter.from_payload(val) } # rubocop:disable Style/HashTransformValues
         | 
| 26 57 | 
             
                  end
         | 
| 27 58 |  | 
| 59 | 
            +
                  def self.headers_to_proto(headers, converter)
         | 
| 60 | 
            +
                    return nil if headers.nil? || headers.empty?
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    Api::Common::V1::Header.new(fields: headers_to_proto_hash(headers, converter))
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  def self.headers_to_proto_hash(headers, converter)
         | 
| 66 | 
            +
                    return nil if headers.nil? || headers.empty?
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    headers.transform_values { |val| converter.to_payload(val) }
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  def self.headers_from_proto(headers, converter)
         | 
| 72 | 
            +
                    headers_from_proto_map(headers&.fields, converter)
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  def self.headers_from_proto_map(headers, converter)
         | 
| 76 | 
            +
                    return nil if headers.nil? || headers.size.zero? # rubocop:disable Style/ZeroLengthPredicate -- Google Maps don't have empty
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                    headers.each_with_object({}) do |(key, val), h| # rubocop:disable Style/HashTransformValues
         | 
| 79 | 
            +
                      # @type var h: Hash[String, Object?]
         | 
| 80 | 
            +
                      h[key] = converter.from_payload(val)
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
             | 
| 28 84 | 
             
                  def self.string_or(str, default = nil)
         | 
| 29 85 | 
             
                    str && !str.empty? ? str : default
         | 
| 30 86 | 
             
                  end
         | 
| @@ -49,6 +105,61 @@ module Temporalio | |
| 49 105 |  | 
| 50 106 | 
             
                    converter.to_payloads(values).payloads.to_ary
         | 
| 51 107 | 
             
                  end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  def self.assert_non_reserved_name(name)
         | 
| 110 | 
            +
                    name = name&.to_s # In case it's a symbol or not present
         | 
| 111 | 
            +
                    return unless name
         | 
| 112 | 
            +
                    raise "'#{name}' cannot start with '__temporal_'" if name.start_with?('__temporal_')
         | 
| 113 | 
            +
                    # Might as well disable __stack_trace and __enhanced_stack_trace everywhere even though technically it's only
         | 
| 114 | 
            +
                    # reserved for queries
         | 
| 115 | 
            +
                    raise "'#{name}' name invalid" if name == '__stack_trace' || name == '__enhanced_stack_trace'
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  def self.reserved_name?(name)
         | 
| 119 | 
            +
                    name = name&.to_s # In case it's a symbol or not present
         | 
| 120 | 
            +
                    return false unless name
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                    name.start_with?('__temporal_') || name == '__stack_trace' || name == '__enhanced_stack_trace'
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  def self.to_user_metadata(summary, details, converter)
         | 
| 126 | 
            +
                    return nil if (!summary || summary.empty?) && (!details || details.empty?)
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                    metadata = Temporalio::Api::Sdk::V1::UserMetadata.new
         | 
| 129 | 
            +
                    metadata.summary = converter.to_payload(summary) if summary && !summary.empty?
         | 
| 130 | 
            +
                    metadata.details = converter.to_payload(details) if details && !details.empty?
         | 
| 131 | 
            +
                    metadata
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                  def self.from_user_metadata(metadata, converter)
         | 
| 135 | 
            +
                    [
         | 
| 136 | 
            +
                      (converter.from_payload(metadata.summary) if metadata&.summary), #: String?
         | 
| 137 | 
            +
                      (converter.from_payload(metadata.details) if metadata&.details) #: String?
         | 
| 138 | 
            +
                    ]
         | 
| 139 | 
            +
                  end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                  class LazyMemo
         | 
| 142 | 
            +
                    def initialize(raw_memo, converter)
         | 
| 143 | 
            +
                      @raw_memo = raw_memo
         | 
| 144 | 
            +
                      @converter = converter
         | 
| 145 | 
            +
                    end
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                    def get
         | 
| 148 | 
            +
                      @memo = ProtoUtils.memo_from_proto(@raw_memo, @converter) unless defined?(@memo)
         | 
| 149 | 
            +
                      @memo
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  class LazySearchAttributes
         | 
| 154 | 
            +
                    def initialize(raw_search_attributes)
         | 
| 155 | 
            +
                      @raw_search_attributes = raw_search_attributes
         | 
| 156 | 
            +
                    end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                    def get
         | 
| 159 | 
            +
                      @search_attributes = SearchAttributes._from_proto(@raw_search_attributes) unless defined?(@search_attributes)
         | 
| 160 | 
            +
                      @search_attributes
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
                  end
         | 
| 52 163 | 
             
                end
         | 
| 53 164 | 
             
              end
         | 
| 54 165 | 
             
            end
         | 
| @@ -3,6 +3,7 @@ | |
| 3 3 | 
             
            require 'temporalio/activity'
         | 
| 4 4 | 
             
            require 'temporalio/activity/definition'
         | 
| 5 5 | 
             
            require 'temporalio/cancellation'
         | 
| 6 | 
            +
            require 'temporalio/converters/raw_value'
         | 
| 6 7 | 
             
            require 'temporalio/internal/bridge/api'
         | 
| 7 8 | 
             
            require 'temporalio/internal/proto_utils'
         | 
| 8 9 | 
             
            require 'temporalio/scoped_logger'
         | 
| @@ -11,14 +12,17 @@ require 'temporalio/worker/interceptor' | |
| 11 12 | 
             
            module Temporalio
         | 
| 12 13 | 
             
              module Internal
         | 
| 13 14 | 
             
                module Worker
         | 
| 15 | 
            +
                  # Worker for handling activity tasks. Upon overarching worker shutdown, {wait_all_complete} should be used to wait
         | 
| 16 | 
            +
                  # for the activities to complete.
         | 
| 14 17 | 
             
                  class ActivityWorker
         | 
| 15 18 | 
             
                    LOG_TASKS = false
         | 
| 16 19 |  | 
| 17 20 | 
             
                    attr_reader :worker, :bridge_worker
         | 
| 18 21 |  | 
| 19 | 
            -
                    def initialize(worker | 
| 22 | 
            +
                    def initialize(worker:, bridge_worker:)
         | 
| 20 23 | 
             
                      @worker = worker
         | 
| 21 24 | 
             
                      @bridge_worker = bridge_worker
         | 
| 25 | 
            +
                      @runtime_metric_meter = worker.options.client.connection.options.runtime.metric_meter
         | 
| 22 26 |  | 
| 23 27 | 
             
                      # Create shared logger that gives scoped activity details
         | 
| 24 28 | 
             
                      @scoped_logger = ScopedLogger.new(@worker.options.logger)
         | 
| @@ -26,12 +30,13 @@ module Temporalio | |
| 26 30 | 
             
                        Activity::Context.current_or_nil&._scoped_logger_info
         | 
| 27 31 | 
             
                      }
         | 
| 28 32 |  | 
| 29 | 
            -
                      # Build up activity hash by name, failing if any fail validation
         | 
| 33 | 
            +
                      # Build up activity hash by name (can be nil for dynamic), failing if any fail validation
         | 
| 30 34 | 
             
                      @activities = worker.options.activities.each_with_object({}) do |act, hash|
         | 
| 31 35 | 
             
                        # Class means create each time, instance means just call, definition
         | 
| 32 36 | 
             
                        # does nothing special
         | 
| 33 | 
            -
                        defn = Activity::Definition.from_activity(act)
         | 
| 37 | 
            +
                        defn = Activity::Definition::Info.from_activity(act)
         | 
| 34 38 | 
             
                        # Confirm name not in use
         | 
| 39 | 
            +
                        raise ArgumentError, 'Only one dynamic activity allowed' if !defn.name && hash.key?(defn.name)
         | 
| 35 40 | 
             
                        raise ArgumentError, "Multiple activities named #{defn.name}" if hash.key?(defn.name)
         | 
| 36 41 |  | 
| 37 42 | 
             
                        # Confirm executor is a known executor and let it initialize
         | 
| @@ -88,8 +93,10 @@ module Temporalio | |
| 88 93 | 
             
                    def handle_start_task(task_token, start)
         | 
| 89 94 | 
             
                      set_running_activity(task_token, nil)
         | 
| 90 95 |  | 
| 91 | 
            -
                      # Find activity definition
         | 
| 96 | 
            +
                      # Find activity definition, falling back to dynamic if not found and not reserved name
         | 
| 92 97 | 
             
                      defn = @activities[start.activity_type]
         | 
| 98 | 
            +
                      defn = @activities[nil] if !defn && !Internal::ProtoUtils.reserved_name?(start.activity_type)
         | 
| 99 | 
            +
             | 
| 93 100 | 
             
                      if defn.nil?
         | 
| 94 101 | 
             
                        raise Error::ApplicationError.new(
         | 
| 95 102 | 
             
                          "Activity #{start.activity_type} for workflow #{start.workflow_execution.workflow_id} " \
         | 
| @@ -109,7 +116,7 @@ module Temporalio | |
| 109 116 | 
             
                        # Unset at the end
         | 
| 110 117 | 
             
                        Activity::Context._current_executor = nil
         | 
| 111 118 | 
             
                      end
         | 
| 112 | 
            -
                    rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
         | 
| 119 | 
            +
                    rescue Exception => e # rubocop:disable Lint/RescueException -- We are intending to catch everything here
         | 
| 113 120 | 
             
                      remove_running_activity(task_token)
         | 
| 114 121 | 
             
                      @scoped_logger.warn("Failed starting activity #{start.activity_type}")
         | 
| 115 122 | 
             
                      @scoped_logger.warn(e)
         | 
| @@ -158,17 +165,19 @@ module Temporalio | |
| 158 165 | 
             
                        activity_id: start.activity_id,
         | 
| 159 166 | 
             
                        activity_type: start.activity_type,
         | 
| 160 167 | 
             
                        attempt: start.attempt,
         | 
| 161 | 
            -
                        current_attempt_scheduled_time:  | 
| 168 | 
            +
                        current_attempt_scheduled_time: Internal::ProtoUtils.timestamp_to_time(
         | 
| 169 | 
            +
                          start.current_attempt_scheduled_time
         | 
| 170 | 
            +
                        ) || raise, # Never nil
         | 
| 162 171 | 
             
                        heartbeat_details: ProtoUtils.convert_from_payload_array(
         | 
| 163 172 | 
             
                          @worker.options.client.data_converter,
         | 
| 164 173 | 
             
                          start.heartbeat_details.to_ary
         | 
| 165 174 | 
             
                        ),
         | 
| 166 | 
            -
                        heartbeat_timeout: start.heartbeat_timeout | 
| 175 | 
            +
                        heartbeat_timeout: Internal::ProtoUtils.duration_to_seconds(start.heartbeat_timeout),
         | 
| 167 176 | 
             
                        local?: start.is_local,
         | 
| 168 | 
            -
                        schedule_to_close_timeout: start.schedule_to_close_timeout | 
| 169 | 
            -
                        scheduled_time: start.scheduled_time | 
| 170 | 
            -
                        start_to_close_timeout: start.start_to_close_timeout | 
| 171 | 
            -
                        started_time: start.started_time | 
| 177 | 
            +
                        schedule_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.schedule_to_close_timeout),
         | 
| 178 | 
            +
                        scheduled_time: Internal::ProtoUtils.timestamp_to_time(start.scheduled_time) || raise, # Never nil
         | 
| 179 | 
            +
                        start_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.start_to_close_timeout),
         | 
| 180 | 
            +
                        started_time: Internal::ProtoUtils.timestamp_to_time(start.started_time) || raise, # Never nil
         | 
| 172 181 | 
             
                        task_queue: @worker.options.task_queue,
         | 
| 173 182 | 
             
                        task_token:,
         | 
| 174 183 | 
             
                        workflow_id: start.workflow_execution.workflow_id,
         | 
| @@ -178,27 +187,34 @@ module Temporalio | |
| 178 187 | 
             
                      ).freeze
         | 
| 179 188 |  | 
| 180 189 | 
             
                      # Build input
         | 
| 181 | 
            -
                      input = Temporalio::Worker::Interceptor:: | 
| 190 | 
            +
                      input = Temporalio::Worker::Interceptor::Activity::ExecuteInput.new(
         | 
| 182 191 | 
             
                        proc: defn.proc,
         | 
| 183 | 
            -
                         | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 192 | 
            +
                        # If the activity wants raw_args, we only decode we don't convert
         | 
| 193 | 
            +
                        args: if defn.raw_args
         | 
| 194 | 
            +
                                payloads = start.input.to_ary
         | 
| 195 | 
            +
                                codec = @worker.options.client.data_converter.payload_codec
         | 
| 196 | 
            +
                                payloads = codec.decode(payloads) if codec
         | 
| 197 | 
            +
                                payloads.map { |p| Temporalio::Converters::RawValue.new(p) }
         | 
| 198 | 
            +
                              else
         | 
| 199 | 
            +
                                ProtoUtils.convert_from_payload_array(@worker.options.client.data_converter, start.input.to_ary)
         | 
| 200 | 
            +
                              end,
         | 
| 201 | 
            +
                        headers: ProtoUtils.headers_from_proto_map(start.header_fields, @worker.options.client.data_converter) || {}
         | 
| 188 202 | 
             
                      )
         | 
| 189 203 |  | 
| 190 204 | 
             
                      # Run
         | 
| 191 205 | 
             
                      activity = RunningActivity.new(
         | 
| 206 | 
            +
                        worker: @worker,
         | 
| 192 207 | 
             
                        info:,
         | 
| 193 208 | 
             
                        cancellation: Cancellation.new,
         | 
| 194 209 | 
             
                        worker_shutdown_cancellation: @worker._worker_shutdown_cancellation,
         | 
| 195 210 | 
             
                        payload_converter: @worker.options.client.data_converter.payload_converter,
         | 
| 196 | 
            -
                        logger: @scoped_logger
         | 
| 211 | 
            +
                        logger: @scoped_logger,
         | 
| 212 | 
            +
                        runtime_metric_meter: @runtime_metric_meter
         | 
| 197 213 | 
             
                      )
         | 
| 198 214 | 
             
                      Activity::Context._current_executor&.set_activity_context(defn, activity)
         | 
| 199 215 | 
             
                      set_running_activity(task_token, activity)
         | 
| 200 | 
            -
                      run_activity(activity, input)
         | 
| 201 | 
            -
                    rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
         | 
| 216 | 
            +
                      run_activity(defn, activity, input)
         | 
| 217 | 
            +
                    rescue Exception => e # rubocop:disable Lint/RescueException -- We are intending to catch everything here
         | 
| 202 218 | 
             
                      @scoped_logger.warn("Failed starting or sending completion for activity #{start.activity_type}")
         | 
| 203 219 | 
             
                      @scoped_logger.warn(e)
         | 
| 204 220 | 
             
                      # This means that the activity couldn't start or send completion (run
         | 
| @@ -223,12 +239,15 @@ module Temporalio | |
| 223 239 | 
             
                      remove_running_activity(task_token)
         | 
| 224 240 | 
             
                    end
         | 
| 225 241 |  | 
| 226 | 
            -
                    def run_activity(activity, input)
         | 
| 242 | 
            +
                    def run_activity(defn, activity, input)
         | 
| 227 243 | 
             
                      result = begin
         | 
| 244 | 
            +
                        # Create the instance. We choose to do this before interceptors so that it is available in the interceptor.
         | 
| 245 | 
            +
                        activity.instance = defn.instance.is_a?(Proc) ? defn.instance.call : defn.instance # steep:ignore
         | 
| 246 | 
            +
             | 
| 228 247 | 
             
                        # Build impl with interceptors
         | 
| 229 | 
            -
                        # @type var impl: Temporalio::Worker::Interceptor:: | 
| 248 | 
            +
                        # @type var impl: Temporalio::Worker::Interceptor::Activity::Inbound
         | 
| 230 249 | 
             
                        impl = InboundImplementation.new(self)
         | 
| 231 | 
            -
                        impl = @worker. | 
| 250 | 
            +
                        impl = @worker._activity_interceptors.reverse_each.reduce(impl) do |acc, int|
         | 
| 232 251 | 
             
                          int.intercept_activity(acc)
         | 
| 233 252 | 
             
                        end
         | 
| 234 253 | 
             
                        impl.init(OutboundImplementation.new(self))
         | 
| @@ -242,7 +261,7 @@ module Temporalio | |
| 242 261 | 
             
                            result: @worker.options.client.data_converter.to_payload(result)
         | 
| 243 262 | 
             
                          )
         | 
| 244 263 | 
             
                        )
         | 
| 245 | 
            -
                      rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
         | 
| 264 | 
            +
                      rescue Exception => e # rubocop:disable Lint/RescueException -- We are intending to catch everything here
         | 
| 246 265 | 
             
                        if e.is_a?(Activity::CompleteAsyncError)
         | 
| 247 266 | 
             
                          # Wanting to complete async
         | 
| 248 267 | 
             
                          @scoped_logger.debug('Completing activity asynchronously')
         | 
| @@ -280,20 +299,24 @@ module Temporalio | |
| 280 299 |  | 
| 281 300 | 
             
                    class RunningActivity < Activity::Context
         | 
| 282 301 | 
             
                      attr_reader :info, :cancellation, :worker_shutdown_cancellation, :payload_converter, :logger
         | 
| 283 | 
            -
                      attr_accessor :_outbound_impl, :_server_requested_cancel
         | 
| 302 | 
            +
                      attr_accessor :instance, :_outbound_impl, :_server_requested_cancel
         | 
| 284 303 |  | 
| 285 304 | 
             
                      def initialize( # rubocop:disable Lint/MissingSuper
         | 
| 305 | 
            +
                        worker:,
         | 
| 286 306 | 
             
                        info:,
         | 
| 287 307 | 
             
                        cancellation:,
         | 
| 288 308 | 
             
                        worker_shutdown_cancellation:,
         | 
| 289 309 | 
             
                        payload_converter:,
         | 
| 290 | 
            -
                        logger | 
| 310 | 
            +
                        logger:,
         | 
| 311 | 
            +
                        runtime_metric_meter:
         | 
| 291 312 | 
             
                      )
         | 
| 313 | 
            +
                        @worker = worker
         | 
| 292 314 | 
             
                        @info = info
         | 
| 293 315 | 
             
                        @cancellation = cancellation
         | 
| 294 316 | 
             
                        @worker_shutdown_cancellation = worker_shutdown_cancellation
         | 
| 295 317 | 
             
                        @payload_converter = payload_converter
         | 
| 296 318 | 
             
                        @logger = logger
         | 
| 319 | 
            +
                        @runtime_metric_meter = runtime_metric_meter
         | 
| 297 320 | 
             
                        @_outbound_impl = nil
         | 
| 298 321 | 
             
                        @_server_requested_cancel = false
         | 
| 299 322 | 
             
                      end
         | 
| @@ -301,11 +324,28 @@ module Temporalio | |
| 301 324 | 
             
                      def heartbeat(*details)
         | 
| 302 325 | 
             
                        raise 'Implementation not set yet' if _outbound_impl.nil?
         | 
| 303 326 |  | 
| 304 | 
            -
                         | 
| 327 | 
            +
                        # No-op if local
         | 
| 328 | 
            +
                        return if info.local?
         | 
| 329 | 
            +
             | 
| 330 | 
            +
                        _outbound_impl.heartbeat(Temporalio::Worker::Interceptor::Activity::HeartbeatInput.new(details:))
         | 
| 331 | 
            +
                      end
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                      def metric_meter
         | 
| 334 | 
            +
                        @metric_meter ||= @runtime_metric_meter.with_additional_attributes(
         | 
| 335 | 
            +
                          {
         | 
| 336 | 
            +
                            namespace: info.workflow_namespace,
         | 
| 337 | 
            +
                            task_queue: info.task_queue,
         | 
| 338 | 
            +
                            activity_type: info.activity_type
         | 
| 339 | 
            +
                          }
         | 
| 340 | 
            +
                        )
         | 
| 341 | 
            +
                      end
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                      def client
         | 
| 344 | 
            +
                        @worker.client
         | 
| 305 345 | 
             
                      end
         | 
| 306 346 | 
             
                    end
         | 
| 307 347 |  | 
| 308 | 
            -
                    class InboundImplementation < Temporalio::Worker::Interceptor:: | 
| 348 | 
            +
                    class InboundImplementation < Temporalio::Worker::Interceptor::Activity::Inbound
         | 
| 309 349 | 
             
                      def initialize(worker)
         | 
| 310 350 | 
             
                        super(nil) # steep:ignore
         | 
| 311 351 | 
             
                        @worker = worker
         | 
| @@ -323,7 +363,7 @@ module Temporalio | |
| 323 363 | 
             
                      end
         | 
| 324 364 | 
             
                    end
         | 
| 325 365 |  | 
| 326 | 
            -
                    class OutboundImplementation < Temporalio::Worker::Interceptor:: | 
| 366 | 
            +
                    class OutboundImplementation < Temporalio::Worker::Interceptor::Activity::Outbound
         | 
| 327 367 | 
             
                      def initialize(worker)
         | 
| 328 368 | 
             
                        super(nil) # steep:ignore
         | 
| 329 369 | 
             
                        @worker = worker
         | 
| @@ -6,6 +6,8 @@ require 'temporalio/internal/bridge/worker' | |
| 6 6 | 
             
            module Temporalio
         | 
| 7 7 | 
             
              module Internal
         | 
| 8 8 | 
             
                module Worker
         | 
| 9 | 
            +
                  # Primary worker (re)actor-style event handler. This handles multiple workers, receiving events from the bridge,
         | 
| 10 | 
            +
                  # and handling a user block.
         | 
| 9 11 | 
             
                  class MultiRunner
         | 
| 10 12 | 
             
                    def initialize(workers:, shutdown_signals:)
         | 
| 11 13 | 
             
                      @workers = workers
         | 
| @@ -32,7 +34,7 @@ module Temporalio | |
| 32 34 | 
             
                                           rescue InjectEventForTesting => e
         | 
| 33 35 | 
             
                                             @queue.push(e.event)
         | 
| 34 36 | 
             
                                             @queue.push(Event::BlockSuccess.new(result: e))
         | 
| 35 | 
            -
                                           rescue Exception => e # rubocop:disable Lint/RescueException Intentionally catch all
         | 
| 37 | 
            +
                                           rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally catch all
         | 
| 36 38 | 
             
                                             @queue.push(Event::BlockFailure.new(error: e))
         | 
| 37 39 | 
             
                                           end
         | 
| 38 40 | 
             
                                         else
         | 
| @@ -41,12 +43,22 @@ module Temporalio | |
| 41 43 | 
             
                                           rescue InjectEventForTesting => e
         | 
| 42 44 | 
             
                                             @queue.push(e.event)
         | 
| 43 45 | 
             
                                             @queue.push(Event::BlockSuccess.new(result: e))
         | 
| 44 | 
            -
                                           rescue Exception => e # rubocop:disable Lint/RescueException Intentionally catch all
         | 
| 46 | 
            +
                                           rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally catch all
         | 
| 45 47 | 
             
                                             @queue.push(Event::BlockFailure.new(error: e))
         | 
| 46 48 | 
             
                                           end
         | 
| 47 49 | 
             
                                         end
         | 
| 48 50 | 
             
                    end
         | 
| 49 51 |  | 
| 52 | 
            +
                    def apply_workflow_activation_decoded(workflow_worker:, activation:)
         | 
| 53 | 
            +
                      @queue.push(Event::WorkflowActivationDecoded.new(workflow_worker:, activation:))
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    def apply_workflow_activation_complete(workflow_worker:, activation_completion:, encoded:)
         | 
| 57 | 
            +
                      @queue.push(Event::WorkflowActivationComplete.new(
         | 
| 58 | 
            +
                                    workflow_worker:, activation_completion:, encoded:, completion_complete_queue: @queue
         | 
| 59 | 
            +
                                  ))
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
             | 
| 50 62 | 
             
                    def raise_in_thread_or_fiber_block(error)
         | 
| 51 63 | 
             
                      @thread_or_fiber&.raise(error)
         | 
| 52 64 | 
             
                    end
         | 
| @@ -80,22 +92,25 @@ module Temporalio | |
| 80 92 | 
             
                      # * [worker index, :activity/:workflow, error] - poll fail
         | 
| 81 93 | 
             
                      # * [worker index, :activity/:workflow, nil] - worker shutdown
         | 
| 82 94 | 
             
                      # * [nil, nil, nil] - all pollers done
         | 
| 95 | 
            +
                      # * [-1, run_id_string, error_or_nil] - workflow activation completion complete
         | 
| 83 96 | 
             
                      result = @queue.pop
         | 
| 84 97 | 
             
                      if result.is_a?(Event)
         | 
| 85 98 | 
             
                        result
         | 
| 86 99 | 
             
                      else
         | 
| 87 | 
            -
                         | 
| 88 | 
            -
                        if  | 
| 100 | 
            +
                        first, second, third = result
         | 
| 101 | 
            +
                        if first.nil? || second.nil?
         | 
| 89 102 | 
             
                          Event::AllPollersShutDown.instance
         | 
| 103 | 
            +
                        elsif first == -1
         | 
| 104 | 
            +
                          Event::WorkflowActivationCompletionComplete.new(run_id: second, error: third)
         | 
| 90 105 | 
             
                        else
         | 
| 91 | 
            -
                          worker = @workers[ | 
| 92 | 
            -
                          case  | 
| 106 | 
            +
                          worker = @workers[first]
         | 
| 107 | 
            +
                          case third
         | 
| 93 108 | 
             
                          when nil
         | 
| 94 | 
            -
                            Event::PollerShutDown.new(worker:, worker_type:)
         | 
| 109 | 
            +
                            Event::PollerShutDown.new(worker:, worker_type: second)
         | 
| 95 110 | 
             
                          when Exception
         | 
| 96 | 
            -
                            Event::PollFailure.new(worker:, worker_type | 
| 111 | 
            +
                            Event::PollFailure.new(worker:, worker_type: second, error: third)
         | 
| 97 112 | 
             
                          else
         | 
| 98 | 
            -
                            Event::PollSuccess.new(worker:, worker_type | 
| 113 | 
            +
                            Event::PollSuccess.new(worker:, worker_type: second, bytes: third)
         | 
| 99 114 | 
             
                          end
         | 
| 100 115 | 
             
                        end
         | 
| 101 116 | 
             
                      end
         | 
| @@ -122,6 +137,35 @@ module Temporalio | |
| 122 137 | 
             
                        end
         | 
| 123 138 | 
             
                      end
         | 
| 124 139 |  | 
| 140 | 
            +
                      class WorkflowActivationDecoded < Event
         | 
| 141 | 
            +
                        attr_reader :workflow_worker, :activation
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                        def initialize(workflow_worker:, activation:) # rubocop:disable Lint/MissingSuper
         | 
| 144 | 
            +
                          @workflow_worker = workflow_worker
         | 
| 145 | 
            +
                          @activation = activation
         | 
| 146 | 
            +
                        end
         | 
| 147 | 
            +
                      end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                      class WorkflowActivationComplete < Event
         | 
| 150 | 
            +
                        attr_reader :workflow_worker, :activation_completion, :encoded, :completion_complete_queue
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                        def initialize(workflow_worker:, activation_completion:, encoded:, completion_complete_queue:) # rubocop:disable Lint/MissingSuper
         | 
| 153 | 
            +
                          @workflow_worker = workflow_worker
         | 
| 154 | 
            +
                          @activation_completion = activation_completion
         | 
| 155 | 
            +
                          @encoded = encoded
         | 
| 156 | 
            +
                          @completion_complete_queue = completion_complete_queue
         | 
| 157 | 
            +
                        end
         | 
| 158 | 
            +
                      end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                      class WorkflowActivationCompletionComplete < Event
         | 
| 161 | 
            +
                        attr_reader :run_id, :error
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                        def initialize(run_id:, error:) # rubocop:disable Lint/MissingSuper
         | 
| 164 | 
            +
                          @run_id = run_id
         | 
| 165 | 
            +
                          @error = error
         | 
| 166 | 
            +
                        end
         | 
| 167 | 
            +
                      end
         | 
| 168 | 
            +
             | 
| 125 169 | 
             
                      class PollerShutDown < Event
         | 
| 126 170 | 
             
                        attr_reader :worker, :worker_type
         | 
| 127 171 |  | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'temporalio/cancellation'
         | 
| 4 | 
            +
            require 'temporalio/workflow'
         | 
| 5 | 
            +
            require 'temporalio/workflow/child_workflow_handle'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Temporalio
         | 
| 8 | 
            +
              module Internal
         | 
| 9 | 
            +
                module Worker
         | 
| 10 | 
            +
                  class WorkflowInstance
         | 
| 11 | 
            +
                    # Implementation of the child workflow handle.
         | 
| 12 | 
            +
                    class ChildWorkflowHandle < Workflow::ChildWorkflowHandle
         | 
| 13 | 
            +
                      attr_reader :id, :first_execution_run_id
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                      def initialize(id:, first_execution_run_id:, instance:, cancellation:, cancel_callback_key:) # rubocop:disable Lint/MissingSuper
         | 
| 16 | 
            +
                        @id = id
         | 
| 17 | 
            +
                        @first_execution_run_id = first_execution_run_id
         | 
| 18 | 
            +
                        @instance = instance
         | 
| 19 | 
            +
                        @cancellation = cancellation
         | 
| 20 | 
            +
                        @cancel_callback_key = cancel_callback_key
         | 
| 21 | 
            +
                        @resolution = nil
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                      def result
         | 
| 25 | 
            +
                        # Notice that we actually provide a detached cancellation here instead of defaulting to workflow
         | 
| 26 | 
            +
                        # cancellation because we don't want workflow cancellation (or a user-provided cancellation to this result
         | 
| 27 | 
            +
                        # call) to be able to interrupt waiting on a child that may be processing the cancellation.
         | 
| 28 | 
            +
                        Workflow.wait_condition(cancellation: Cancellation.new) { @resolution }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                        case @resolution.status
         | 
| 31 | 
            +
                        when :completed
         | 
| 32 | 
            +
                          @instance.payload_converter.from_payload(@resolution.completed.result)
         | 
| 33 | 
            +
                        when :failed
         | 
| 34 | 
            +
                          raise @instance.failure_converter.from_failure(@resolution.failed.failure, @instance.payload_converter)
         | 
| 35 | 
            +
                        when :cancelled
         | 
| 36 | 
            +
                          raise @instance.failure_converter.from_failure(@resolution.cancelled.failure, @instance.payload_converter)
         | 
| 37 | 
            +
                        else
         | 
| 38 | 
            +
                          raise "Unrecognized resolution status: #{@resolution.status}"
         | 
| 39 | 
            +
                        end
         | 
| 40 | 
            +
                      end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      def _resolve(resolution)
         | 
| 43 | 
            +
                        @cancellation.remove_cancel_callback(@cancel_callback_key)
         | 
| 44 | 
            +
                        @resolution = resolution
         | 
| 45 | 
            +
                      end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      def signal(signal, *args, cancellation: Workflow.cancellation)
         | 
| 48 | 
            +
                        @instance.context._signal_child_workflow(id:, signal:, args:, cancellation:)
         | 
| 49 | 
            +
                      end
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         |