temporalio 0.2.0-x86_64-linux → 0.4.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.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/Gemfile +27 -0
- data/Rakefile +101 -0
- 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.so +0 -0
- data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/{3.1 → 3.4}/temporalio_bridge.so +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 +77 -8
    
        data/lib/temporalio/runtime.rb
    CHANGED
    
    | @@ -1,6 +1,10 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'temporalio/internal/bridge'
         | 
| 3 4 | 
             
            require 'temporalio/internal/bridge/runtime'
         | 
| 5 | 
            +
            require 'temporalio/internal/metric'
         | 
| 6 | 
            +
            require 'temporalio/metric'
         | 
| 7 | 
            +
            require 'temporalio/runtime/metric_buffer'
         | 
| 4 8 |  | 
| 5 9 | 
             
            module Temporalio
         | 
| 6 10 | 
             
              # Runtime for Temporal Ruby SDK.
         | 
| @@ -9,6 +13,11 @@ module Temporalio | |
| 9 13 | 
             
              # before any clients are created, and set it via {default=}. Every time a new runtime is created, a new internal Rust
         | 
| 10 14 | 
             
              # thread pool is created.
         | 
| 11 15 | 
             
              class Runtime
         | 
| 16 | 
            +
                TelemetryOptions = Data.define(
         | 
| 17 | 
            +
                  :logging,
         | 
| 18 | 
            +
                  :metrics
         | 
| 19 | 
            +
                )
         | 
| 20 | 
            +
             | 
| 12 21 | 
             
                # Telemetry options for the runtime.
         | 
| 13 22 | 
             
                #
         | 
| 14 23 | 
             
                # @!attribute logging
         | 
| @@ -16,15 +25,13 @@ module Temporalio | |
| 16 25 | 
             
                #     to nil to disable logging.
         | 
| 17 26 | 
             
                # @!attribute metrics
         | 
| 18 27 | 
             
                #   @return [MetricsOptions, nil] Metrics options.
         | 
| 19 | 
            -
                TelemetryOptions | 
| 20 | 
            -
                   | 
| 21 | 
            -
                   | 
| 22 | 
            -
                   | 
| 23 | 
            -
             | 
| 24 | 
            -
                  #  | 
| 25 | 
            -
                  def initialize( | 
| 26 | 
            -
                    # @type var kwargs: untyped
         | 
| 27 | 
            -
                    kwargs[:logging] = LoggingOptions.new unless kwargs.key?(:logging)
         | 
| 28 | 
            +
                class TelemetryOptions
         | 
| 29 | 
            +
                  # Create telemetry options.
         | 
| 30 | 
            +
                  #
         | 
| 31 | 
            +
                  # @param logging [LoggingOptions, nil] Logging options, default is new {LoggingOptions} with no parameters. Can be
         | 
| 32 | 
            +
                  #   set to nil to disable logging.
         | 
| 33 | 
            +
                  # @param metrics [MetricsOptions, nil] Metrics options.
         | 
| 34 | 
            +
                  def initialize(logging: LoggingOptions.new, metrics: nil)
         | 
| 28 35 | 
             
                    super
         | 
| 29 36 | 
             
                  end
         | 
| 30 37 |  | 
| @@ -38,20 +45,21 @@ module Temporalio | |
| 38 45 | 
             
                  end
         | 
| 39 46 | 
             
                end
         | 
| 40 47 |  | 
| 48 | 
            +
                LoggingOptions = Data.define(
         | 
| 49 | 
            +
                  :log_filter
         | 
| 50 | 
            +
                  # TODO(cretz): forward_to
         | 
| 51 | 
            +
                )
         | 
| 52 | 
            +
             | 
| 41 53 | 
             
                # Logging options for runtime telemetry.
         | 
| 42 54 | 
             
                #
         | 
| 43 55 | 
             
                # @!attribute log_filter
         | 
| 44 56 | 
             
                #   @return [LoggingFilterOptions, String] Logging filter for Core, default is new {LoggingFilterOptions} with no
         | 
| 45 57 | 
             
                #     parameters.
         | 
| 46 | 
            -
                LoggingOptions | 
| 47 | 
            -
                   | 
| 48 | 
            -
                  # | 
| 49 | 
            -
                   | 
| 50 | 
            -
             | 
| 51 | 
            -
                  # @!visibility private
         | 
| 52 | 
            -
                  def initialize(**kwargs)
         | 
| 53 | 
            -
                    # @type var kwargs: untyped
         | 
| 54 | 
            -
                    kwargs[:log_filter] = LoggingFilterOptions.new unless kwargs.key?(:log_filter)
         | 
| 58 | 
            +
                class LoggingOptions
         | 
| 59 | 
            +
                  # Create logging options
         | 
| 60 | 
            +
                  #
         | 
| 61 | 
            +
                  # @param log_filter [LoggingFilterOptions, String] Logging filter for Core.
         | 
| 62 | 
            +
                  def initialize(log_filter: LoggingFilterOptions.new)
         | 
| 55 63 | 
             
                    super
         | 
| 56 64 | 
             
                  end
         | 
| 57 65 |  | 
| @@ -70,22 +78,23 @@ module Temporalio | |
| 70 78 | 
             
                  end
         | 
| 71 79 | 
             
                end
         | 
| 72 80 |  | 
| 81 | 
            +
                LoggingFilterOptions = Data.define(
         | 
| 82 | 
            +
                  :core_level,
         | 
| 83 | 
            +
                  :other_level
         | 
| 84 | 
            +
                )
         | 
| 85 | 
            +
             | 
| 73 86 | 
             
                # Logging filter options for Core.
         | 
| 74 87 | 
             
                #
         | 
| 75 88 | 
             
                # @!attribute core_level
         | 
| 76 | 
            -
                #   @return ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] Log level for Core log messages | 
| 89 | 
            +
                #   @return ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] Log level for Core log messages.
         | 
| 77 90 | 
             
                # @!attribute other_level
         | 
| 78 | 
            -
                #   @return ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] Log level for other Rust log messages | 
| 79 | 
            -
                LoggingFilterOptions | 
| 80 | 
            -
                   | 
| 81 | 
            -
                   | 
| 82 | 
            -
                   | 
| 83 | 
            -
             | 
| 84 | 
            -
                   | 
| 85 | 
            -
                  def initialize(**kwargs)
         | 
| 86 | 
            -
                    # @type var kwargs: untyped
         | 
| 87 | 
            -
                    kwargs[:core_level] = 'WARN' unless kwargs.key?(:core_level)
         | 
| 88 | 
            -
                    kwargs[:other_level] = 'ERROR' unless kwargs.key?(:other_level)
         | 
| 91 | 
            +
                #   @return ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] Log level for other Rust log messages.
         | 
| 92 | 
            +
                class LoggingFilterOptions
         | 
| 93 | 
            +
                  # Create logging filter options.
         | 
| 94 | 
            +
                  #
         | 
| 95 | 
            +
                  # @param core_level ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] Log level for Core log messages.
         | 
| 96 | 
            +
                  # @!attribute other_level ['TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR'] Log level for other Rust log messages.
         | 
| 97 | 
            +
                  def initialize(core_level: 'WARN', other_level: 'ERROR')
         | 
| 89 98 | 
             
                    super
         | 
| 90 99 | 
             
                  end
         | 
| 91 100 |  | 
| @@ -96,32 +105,56 @@ module Temporalio | |
| 96 105 | 
             
                  end
         | 
| 97 106 | 
             
                end
         | 
| 98 107 |  | 
| 108 | 
            +
                MetricsOptions = Data.define(
         | 
| 109 | 
            +
                  :opentelemetry,
         | 
| 110 | 
            +
                  :prometheus,
         | 
| 111 | 
            +
                  :buffer,
         | 
| 112 | 
            +
                  :attach_service_name,
         | 
| 113 | 
            +
                  :global_tags,
         | 
| 114 | 
            +
                  :metric_prefix
         | 
| 115 | 
            +
                )
         | 
| 116 | 
            +
             | 
| 99 117 | 
             
                # Metrics options for runtime telemetry. Either {opentelemetry} or {prometheus} required, but not both.
         | 
| 100 118 | 
             
                #
         | 
| 101 119 | 
             
                # @!attribute opentelemetry
         | 
| 102 120 | 
             
                #   @return [OpenTelemetryMetricsOptions, nil] OpenTelemetry options if using OpenTelemetry. This is mutually
         | 
| 103 | 
            -
                #     exclusive with  | 
| 121 | 
            +
                #     exclusive with `prometheus` and `buffer`.
         | 
| 104 122 | 
             
                # @!attribute prometheus
         | 
| 105 123 | 
             
                #   @return [PrometheusMetricsOptions, nil] Prometheus options if using Prometheus. This is mutually exclusive with
         | 
| 106 | 
            -
                #      | 
| 124 | 
            +
                #     `opentelemetry` and `buffer`.
         | 
| 125 | 
            +
                # @!attribute buffer
         | 
| 126 | 
            +
                #   @return [MetricBuffer, nil] Metric buffer to send all metrics to. This is mutually exclusive with `prometheus`
         | 
| 127 | 
            +
                #     and `opentelemetry`.
         | 
| 107 128 | 
             
                # @!attribute attach_service_name
         | 
| 108 | 
            -
                #   @return [Boolean] Whether to put the service_name on every metric | 
| 129 | 
            +
                #   @return [Boolean] Whether to put the service_name on every metric.
         | 
| 109 130 | 
             
                # @!attribute global_tags
         | 
| 110 131 | 
             
                #   @return [Hash<String, String>, nil] Resource tags to be applied to all metrics.
         | 
| 111 132 | 
             
                # @!attribute metric_prefix
         | 
| 112 | 
            -
                #   @return [String, nil] Prefix to put on every Temporal metric. If unset, defaults to  | 
| 113 | 
            -
                MetricsOptions | 
| 114 | 
            -
                   | 
| 115 | 
            -
                   | 
| 116 | 
            -
                   | 
| 117 | 
            -
                   | 
| 118 | 
            -
                   | 
| 119 | 
            -
                   | 
| 120 | 
            -
             | 
| 121 | 
            -
                  #  | 
| 122 | 
            -
                   | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 133 | 
            +
                #   @return [String, nil] Prefix to put on every Temporal metric. If unset, defaults to `temporal_`.
         | 
| 134 | 
            +
                class MetricsOptions
         | 
| 135 | 
            +
                  # Create metrics options. Either `opentelemetry` or `prometheus` required, but not both.
         | 
| 136 | 
            +
                  #
         | 
| 137 | 
            +
                  # @param opentelemetry [OpenTelemetryMetricsOptions, nil] OpenTelemetry options if using OpenTelemetry. This is
         | 
| 138 | 
            +
                  #   mutually exclusive with `prometheus` and `buffer`.
         | 
| 139 | 
            +
                  # @param prometheus [PrometheusMetricsOptions, nil] Prometheus options if using Prometheus. This is mutually
         | 
| 140 | 
            +
                  #   exclusive with `opentelemetry` and `buffer`.
         | 
| 141 | 
            +
                  # @param buffer [MetricBuffer, nil] Metric buffer to send all metrics to. This is mutually exclusive with
         | 
| 142 | 
            +
                  #   `prometheus` and `opentelemetry`.
         | 
| 143 | 
            +
                  # @param attach_service_name [Boolean] Whether to put the service_name on every metric.
         | 
| 144 | 
            +
                  # @param global_tags [Hash<String, String>, nil] Resource tags to be applied to all metrics.
         | 
| 145 | 
            +
                  # @param metric_prefix [String, nil] Prefix to put on every Temporal metric. If unset, defaults to `temporal_`.
         | 
| 146 | 
            +
                  def initialize(
         | 
| 147 | 
            +
                    opentelemetry: nil,
         | 
| 148 | 
            +
                    prometheus: nil,
         | 
| 149 | 
            +
                    buffer: nil,
         | 
| 150 | 
            +
                    attach_service_name: true,
         | 
| 151 | 
            +
                    global_tags: nil,
         | 
| 152 | 
            +
                    metric_prefix: nil
         | 
| 153 | 
            +
                  )
         | 
| 154 | 
            +
                    if [opentelemetry, prometheus, buffer].count { |v| !v.nil? } > 1
         | 
| 155 | 
            +
                      raise 'Can only have one of opentelemetry, prometheus, or buffer'
         | 
| 156 | 
            +
                    end
         | 
| 157 | 
            +
             | 
| 125 158 | 
             
                    super
         | 
| 126 159 | 
             
                  end
         | 
| 127 160 |  | 
| @@ -131,6 +164,7 @@ module Temporalio | |
| 131 164 | 
             
                    Internal::Bridge::Runtime::MetricsOptions.new(
         | 
| 132 165 | 
             
                      opentelemetry: opentelemetry&._to_bridge,
         | 
| 133 166 | 
             
                      prometheus: prometheus&._to_bridge,
         | 
| 167 | 
            +
                      buffered_with_size: buffer&._buffer_size,
         | 
| 134 168 | 
             
                      attach_service_name:,
         | 
| 135 169 | 
             
                      global_tags:,
         | 
| 136 170 | 
             
                      metric_prefix:
         | 
| @@ -138,6 +172,16 @@ module Temporalio | |
| 138 172 | 
             
                  end
         | 
| 139 173 | 
             
                end
         | 
| 140 174 |  | 
| 175 | 
            +
                OpenTelemetryMetricsOptions = Data.define(
         | 
| 176 | 
            +
                  :url,
         | 
| 177 | 
            +
                  :headers,
         | 
| 178 | 
            +
                  :metric_periodicity,
         | 
| 179 | 
            +
                  :metric_temporality,
         | 
| 180 | 
            +
                  :durations_as_seconds,
         | 
| 181 | 
            +
                  :http,
         | 
| 182 | 
            +
                  :histogram_bucket_overrides
         | 
| 183 | 
            +
                )
         | 
| 184 | 
            +
             | 
| 141 185 | 
             
                # Options for exporting metrics to OpenTelemetry.
         | 
| 142 186 | 
             
                #
         | 
| 143 187 | 
             
                # @!attribute url
         | 
| @@ -152,25 +196,38 @@ module Temporalio | |
| 152 196 | 
             
                # @!attribute durations_as_seconds
         | 
| 153 197 | 
             
                #   @return [Boolean] Whether to use float seconds instead of integer milliseconds for durations, default is
         | 
| 154 198 | 
             
                #     +false+.
         | 
| 155 | 
            -
                 | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
             | 
| 161 | 
            -
                  keyword_init: true
         | 
| 162 | 
            -
                ) do
         | 
| 199 | 
            +
                # @!attribute http
         | 
| 200 | 
            +
                #   @return [Boolean] True if the protocol is HTTP, false if gRPC (the default).
         | 
| 201 | 
            +
                # @!attribute histogram_bucket_overrides
         | 
| 202 | 
            +
                #   @return [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of the hash it the metric
         | 
| 203 | 
            +
                #     name, value is an array of floats for the set of buckets.
         | 
| 204 | 
            +
                class OpenTelemetryMetricsOptions
         | 
| 163 205 | 
             
                  # OpenTelemetry metric temporality.
         | 
| 164 | 
            -
                  module MetricTemporality | 
| 206 | 
            +
                  module MetricTemporality
         | 
| 165 207 | 
             
                    CUMULATIVE = 1
         | 
| 166 208 | 
             
                    DELTA = 2
         | 
| 167 209 | 
             
                  end
         | 
| 168 210 |  | 
| 169 | 
            -
                  #  | 
| 170 | 
            -
                   | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 211 | 
            +
                  # Create OpenTelemetry options.
         | 
| 212 | 
            +
                  #
         | 
| 213 | 
            +
                  # @param url [String] URL for OpenTelemetry endpoint.
         | 
| 214 | 
            +
                  # @param headers [Hash<String, String>, nil] Headers for OpenTelemetry endpoint.
         | 
| 215 | 
            +
                  # @param metric_periodicity [Float, nil] How frequently metrics should be exported, unset uses internal default.
         | 
| 216 | 
            +
                  # @param metric_temporality [MetricTemporality] How frequently metrics should be exported.
         | 
| 217 | 
            +
                  # @param durations_as_seconds [Boolean] Whether to use float seconds instead of integer milliseconds for
         | 
| 218 | 
            +
                  #   durations.
         | 
| 219 | 
            +
                  # @param http [Boolean] True if the protocol is HTTP, false if gRPC (the default).
         | 
| 220 | 
            +
                  # @param histogram_bucket_overrides [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of
         | 
| 221 | 
            +
                  #   the hash it the metric name, value is an array of floats for the set of buckets.
         | 
| 222 | 
            +
                  def initialize(
         | 
| 223 | 
            +
                    url:,
         | 
| 224 | 
            +
                    headers: nil,
         | 
| 225 | 
            +
                    metric_periodicity: nil,
         | 
| 226 | 
            +
                    metric_temporality: MetricTemporality::CUMULATIVE,
         | 
| 227 | 
            +
                    durations_as_seconds: false,
         | 
| 228 | 
            +
                    http: false,
         | 
| 229 | 
            +
                    histogram_bucket_overrides: nil
         | 
| 230 | 
            +
                  )
         | 
| 174 231 | 
             
                    super
         | 
| 175 232 | 
             
                  end
         | 
| 176 233 |  | 
| @@ -186,35 +243,51 @@ module Temporalio | |
| 186 243 | 
             
                                                when MetricTemporality::DELTA then true
         | 
| 187 244 | 
             
                                                else raise 'Unrecognized metric temporality'
         | 
| 188 245 | 
             
                                                end,
         | 
| 189 | 
            -
                      durations_as_seconds | 
| 246 | 
            +
                      durations_as_seconds:,
         | 
| 247 | 
            +
                      http:,
         | 
| 248 | 
            +
                      histogram_bucket_overrides:
         | 
| 190 249 | 
             
                    )
         | 
| 191 250 | 
             
                  end
         | 
| 192 251 | 
             
                end
         | 
| 193 252 |  | 
| 253 | 
            +
                PrometheusMetricsOptions = Data.define(
         | 
| 254 | 
            +
                  :bind_address,
         | 
| 255 | 
            +
                  :counters_total_suffix,
         | 
| 256 | 
            +
                  :unit_suffix,
         | 
| 257 | 
            +
                  :durations_as_seconds,
         | 
| 258 | 
            +
                  :histogram_bucket_overrides
         | 
| 259 | 
            +
                )
         | 
| 260 | 
            +
             | 
| 194 261 | 
             
                # Options for exporting metrics to Prometheus.
         | 
| 195 262 | 
             
                #
         | 
| 196 263 | 
             
                # @!attribute bind_address
         | 
| 197 264 | 
             
                #   @return [String] Address to bind to for Prometheus endpoint.
         | 
| 198 265 | 
             
                # @!attribute counters_total_suffix
         | 
| 199 | 
            -
                #   @return [Boolean] If  | 
| 266 | 
            +
                #   @return [Boolean] If `true`, all counters will include a `_total` suffix.
         | 
| 200 267 | 
             
                # @!attribute unit_suffix
         | 
| 201 | 
            -
                #   @return [Boolean] If  | 
| 268 | 
            +
                #   @return [Boolean] If `true`, all histograms will include the unit in their name as a suffix.
         | 
| 202 269 | 
             
                # @!attribute durations_as_seconds
         | 
| 203 | 
            -
                #   @return [Boolean] Whether to use float seconds instead of integer milliseconds for durations | 
| 204 | 
            -
                # | 
| 205 | 
            -
                 | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 208 | 
            -
                   | 
| 209 | 
            -
                   | 
| 210 | 
            -
                   | 
| 211 | 
            -
             | 
| 212 | 
            -
                  #  | 
| 213 | 
            -
                   | 
| 214 | 
            -
             | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 270 | 
            +
                #   @return [Boolean] Whether to use float seconds instead of integer milliseconds for durations.
         | 
| 271 | 
            +
                # @!attribute histogram_bucket_overrides
         | 
| 272 | 
            +
                #   @return [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of the hash it the metric
         | 
| 273 | 
            +
                #     name, value is an array of floats for the set of buckets.
         | 
| 274 | 
            +
                class PrometheusMetricsOptions
         | 
| 275 | 
            +
                  # Create Prometheus options.
         | 
| 276 | 
            +
                  #
         | 
| 277 | 
            +
                  # @param bind_address [String] Address to bind to for Prometheus endpoint.
         | 
| 278 | 
            +
                  # @param counters_total_suffix [Boolean] If `true`, all counters will include a `_total` suffix.
         | 
| 279 | 
            +
                  # @param unit_suffix [Boolean] If `true`, all histograms will include the unit in their name as a suffix.
         | 
| 280 | 
            +
                  # @param durations_as_seconds [Boolean] Whether to use float seconds instead of integer milliseconds for
         | 
| 281 | 
            +
                  #   durations.
         | 
| 282 | 
            +
                  # @param histogram_bucket_overrides [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of
         | 
| 283 | 
            +
                  #   the hash it the metric name, value is an array of floats for the set of buckets.
         | 
| 284 | 
            +
                  def initialize(
         | 
| 285 | 
            +
                    bind_address:,
         | 
| 286 | 
            +
                    counters_total_suffix: false,
         | 
| 287 | 
            +
                    unit_suffix: false,
         | 
| 288 | 
            +
                    durations_as_seconds: false,
         | 
| 289 | 
            +
                    histogram_bucket_overrides: nil
         | 
| 290 | 
            +
                  )
         | 
| 218 291 | 
             
                    super
         | 
| 219 292 | 
             
                  end
         | 
| 220 293 |  | 
| @@ -225,7 +298,8 @@ module Temporalio | |
| 225 298 | 
             
                      bind_address:,
         | 
| 226 299 | 
             
                      counters_total_suffix:,
         | 
| 227 300 | 
             
                      unit_suffix:,
         | 
| 228 | 
            -
                      durations_as_seconds | 
| 301 | 
            +
                      durations_as_seconds:,
         | 
| 302 | 
            +
                      histogram_bucket_overrides:
         | 
| 229 303 | 
             
                    )
         | 
| 230 304 | 
             
                  end
         | 
| 231 305 | 
             
                end
         | 
| @@ -248,14 +322,21 @@ module Temporalio | |
| 248 322 | 
             
                  @default = runtime
         | 
| 249 323 | 
             
                end
         | 
| 250 324 |  | 
| 325 | 
            +
                # @return [Metric::Meter] Metric meter that can create and record metric values.
         | 
| 326 | 
            +
                attr_reader :metric_meter
         | 
| 327 | 
            +
             | 
| 251 328 | 
             
                # Create new Runtime. For most users, this should only be done once globally. In addition to creating a Rust thread
         | 
| 252 329 | 
             
                # pool, this also consumes a Ruby thread for its lifetime.
         | 
| 253 330 | 
             
                #
         | 
| 254 331 | 
             
                # @param telemetry [TelemetryOptions] Telemetry options to set.
         | 
| 255 332 | 
             
                def initialize(telemetry: TelemetryOptions.new)
         | 
| 333 | 
            +
                  # Set runtime on the buffer which will fail if the buffer is used on another runtime
         | 
| 334 | 
            +
                  telemetry.metrics&.buffer&._set_runtime(self)
         | 
| 335 | 
            +
             | 
| 256 336 | 
             
                  @core_runtime = Internal::Bridge::Runtime.new(
         | 
| 257 337 | 
             
                    Internal::Bridge::Runtime::Options.new(telemetry: telemetry._to_bridge)
         | 
| 258 338 | 
             
                  )
         | 
| 339 | 
            +
                  @metric_meter = Internal::Metric::Meter.create_from_runtime(self) || Metric::Meter.null
         | 
| 259 340 | 
             
                  # We need a thread to run the command loop
         | 
| 260 341 | 
             
                  # TODO(cretz): Is this something users should be concerned about or need control over?
         | 
| 261 342 | 
             
                  Thread.new do
         | 
| @@ -7,7 +7,7 @@ module Temporalio | |
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              # This is represented as a mapping of {SearchAttributes::Key} to object values. This is not a hash though it does have
         | 
| 9 9 | 
             
              # a few hash-like methods and can be converted to a hash via {#to_h}. In some situations, such as in workflows, this
         | 
| 10 | 
            -
              # class is  | 
| 10 | 
            +
              # class is immutable for outside use.
         | 
| 11 11 | 
             
              class SearchAttributes
         | 
| 12 12 | 
             
                # Key for a search attribute.
         | 
| 13 13 | 
             
                class Key
         | 
| @@ -20,7 +20,7 @@ module Temporalio | |
| 20 20 | 
             
                  def initialize(name, type)
         | 
| 21 21 | 
             
                    raise ArgumentError, 'Invalid type' unless Api::Enums::V1::IndexedValueType.lookup(type)
         | 
| 22 22 |  | 
| 23 | 
            -
                    @name = name
         | 
| 23 | 
            +
                    @name = name.to_s
         | 
| 24 24 | 
             
                    @type = type
         | 
| 25 25 | 
             
                  end
         | 
| 26 26 |  | 
| @@ -104,28 +104,54 @@ module Temporalio | |
| 104 104 | 
             
                    @key = key
         | 
| 105 105 | 
             
                    @value = value
         | 
| 106 106 | 
             
                  end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                  # @!visibility private
         | 
| 109 | 
            +
                  def _to_proto_pair
         | 
| 110 | 
            +
                    SearchAttributes._to_proto_pair(key, value)
         | 
| 111 | 
            +
                  end
         | 
| 107 112 | 
             
                end
         | 
| 108 113 |  | 
| 109 114 | 
             
                # @!visibility private
         | 
| 110 | 
            -
                def self. | 
| 111 | 
            -
                  return nil unless proto
         | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 115 | 
            +
                def self._from_proto(proto, disable_mutations: false, never_nil: false)
         | 
| 116 | 
            +
                  return nil unless proto || never_nil
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  attrs = if proto
         | 
| 119 | 
            +
                            unless proto.is_a?(Api::Common::V1::SearchAttributes)
         | 
| 120 | 
            +
                              raise ArgumentError, 'Expected proto search attribute'
         | 
| 121 | 
            +
                            end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                            SearchAttributes.new(proto.indexed_fields.map do |key_name, payload| # rubocop:disable Style/MapToHash
         | 
| 124 | 
            +
                              key = Key.new(key_name, IndexedValueType::PROTO_VALUES[payload.metadata['type']])
         | 
| 125 | 
            +
                              value = _value_from_payload(payload)
         | 
| 126 | 
            +
                              [key, value]
         | 
| 127 | 
            +
                            end.to_h)
         | 
| 128 | 
            +
                          else
         | 
| 129 | 
            +
                            SearchAttributes.new
         | 
| 130 | 
            +
                          end
         | 
| 131 | 
            +
                  attrs._disable_mutations = disable_mutations
         | 
| 132 | 
            +
                  attrs
         | 
| 119 133 | 
             
                end
         | 
| 120 134 |  | 
| 121 135 | 
             
                # @!visibility private
         | 
| 122 | 
            -
                def self. | 
| 136 | 
            +
                def self._value_from_payload(payload)
         | 
| 123 137 | 
             
                  value = Converters::PayloadConverter.default.from_payload(payload)
         | 
| 124 138 | 
             
                  # Time needs to be converted
         | 
| 125 139 | 
             
                  value = Time.iso8601(value) if payload.metadata['type'] == 'DateTime' && value.is_a?(String)
         | 
| 126 140 | 
             
                  value
         | 
| 127 141 | 
             
                end
         | 
| 128 142 |  | 
| 143 | 
            +
                # @!visibility private
         | 
| 144 | 
            +
                def self._to_proto_pair(key, value)
         | 
| 145 | 
            +
                  # We use a default converter, but if type is a time, we need ISO format
         | 
| 146 | 
            +
                  value = value.iso8601 if key.type == IndexedValueType::TIME && value.is_a?(Time)
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  # Convert to payload
         | 
| 149 | 
            +
                  payload = Converters::PayloadConverter.default.to_payload(value)
         | 
| 150 | 
            +
                  payload.metadata['type'] = IndexedValueType::PROTO_NAMES[key.type]
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                  [key.name, payload]
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 129 155 | 
             
                # Create a search attribute collection.
         | 
| 130 156 | 
             
                #
         | 
| 131 157 | 
             
                # @param existing [SearchAttributes, Hash<Key, Object>, nil] Existing collection. This can be another
         | 
| @@ -149,6 +175,7 @@ module Temporalio | |
| 149 175 | 
             
                # @param key [Key] A key to set. This must be a {Key} and the value must be proper for the {Key#type}.
         | 
| 150 176 | 
             
                # @param value [Object, nil] The value to set. If `nil`, the key is removed. The value must be proper for the `key`.
         | 
| 151 177 | 
             
                def []=(key, value)
         | 
| 178 | 
            +
                  _assert_mutations_enabled
         | 
| 152 179 | 
             
                  # Key must be a Key
         | 
| 153 180 | 
             
                  raise ArgumentError, 'Key must be a key' unless key.is_a?(Key)
         | 
| 154 181 |  | 
| @@ -162,33 +189,37 @@ module Temporalio | |
| 162 189 |  | 
| 163 190 | 
             
                # Get a search attribute value for a key.
         | 
| 164 191 | 
             
                #
         | 
| 165 | 
            -
                # @param key [Key, String] The key to find. If this is a {Key}, it will use key equality (i.e. name and | 
| 166 | 
            -
                #   search. If this is a {::String}, the type is not checked when finding the proper key.
         | 
| 192 | 
            +
                # @param key [Key, String, Symbol] The key to find. If this is a {Key}, it will use key equality (i.e. name and
         | 
| 193 | 
            +
                #   type) to search. If this is a {::String}, the type is not checked when finding the proper key.
         | 
| 167 194 | 
             
                # @return [Object, nil] Value if found or `nil` if not.
         | 
| 168 195 | 
             
                def [](key)
         | 
| 169 196 | 
             
                  # Key must be a Key or a string
         | 
| 170 | 
            -
                   | 
| 197 | 
            +
                  case key
         | 
| 198 | 
            +
                  when Key
         | 
| 171 199 | 
             
                    @raw_hash[key]
         | 
| 172 | 
            -
                   | 
| 173 | 
            -
                    @raw_hash.find { |hash_key, _| hash_key.name == key }&.last
         | 
| 200 | 
            +
                  when String, Symbol
         | 
| 201 | 
            +
                    @raw_hash.find { |hash_key, _| hash_key.name == key.to_s }&.last
         | 
| 174 202 | 
             
                  else
         | 
| 175 | 
            -
                    raise ArgumentError, 'Key must be a key or string'
         | 
| 203 | 
            +
                    raise ArgumentError, 'Key must be a key or string/symbol'
         | 
| 176 204 | 
             
                  end
         | 
| 177 205 | 
             
                end
         | 
| 178 206 |  | 
| 179 207 | 
             
                # Delete a search attribute key
         | 
| 180 208 | 
             
                #
         | 
| 181 | 
            -
                # @param key [Key, String] The key to delete. Regardless of whether this is a {Key} or a {::String}, the key | 
| 182 | 
            -
                #   the matching name will be deleted. This means a {Key} with a matching name but different type may be | 
| 209 | 
            +
                # @param key [Key, String, Symbol] The key to delete. Regardless of whether this is a {Key} or a {::String}, the key
         | 
| 210 | 
            +
                #   with the matching name will be deleted. This means a {Key} with a matching name but different type may be
         | 
| 211 | 
            +
                #   deleted.
         | 
| 183 212 | 
             
                def delete(key)
         | 
| 213 | 
            +
                  _assert_mutations_enabled
         | 
| 184 214 | 
             
                  # Key must be a Key or a string, but we delete all values for the
         | 
| 185 215 | 
             
                  # name no matter what
         | 
| 186 | 
            -
                  name =  | 
| 216 | 
            +
                  name = case key
         | 
| 217 | 
            +
                         when Key
         | 
| 187 218 | 
             
                           key.name
         | 
| 188 | 
            -
                          | 
| 189 | 
            -
                           key
         | 
| 219 | 
            +
                         when String, Symbol
         | 
| 220 | 
            +
                           key.to_s
         | 
| 190 221 | 
             
                         else
         | 
| 191 | 
            -
                           raise ArgumentError, 'Key must be a key or string'
         | 
| 222 | 
            +
                           raise ArgumentError, 'Key must be a key or string/symbol'
         | 
| 192 223 | 
             
                         end
         | 
| 193 224 | 
             
                  @raw_hash.delete_if { |hash_key, _| hash_key.name == name }
         | 
| 194 225 | 
             
                end
         | 
| @@ -205,7 +236,9 @@ module Temporalio | |
| 205 236 |  | 
| 206 237 | 
             
                # @return [SearchAttributes] Copy of the search attributes.
         | 
| 207 238 | 
             
                def dup
         | 
| 208 | 
            -
                  SearchAttributes.new(self)
         | 
| 239 | 
            +
                  attrs = SearchAttributes.new(self)
         | 
| 240 | 
            +
                  attrs._disable_mutations = false
         | 
| 241 | 
            +
                  attrs
         | 
| 209 242 | 
             
                end
         | 
| 210 243 |  | 
| 211 244 | 
             
                # @return [Boolean] Whether the set of attributes is empty.
         | 
| @@ -218,6 +251,14 @@ module Temporalio | |
| 218 251 | 
             
                  @raw_hash.length
         | 
| 219 252 | 
             
                end
         | 
| 220 253 |  | 
| 254 | 
            +
                # Check equality.
         | 
| 255 | 
            +
                #
         | 
| 256 | 
            +
                # @param other [SearchAttributes] To compare.
         | 
| 257 | 
            +
                # @return [Boolean] Whether equal.
         | 
| 258 | 
            +
                def ==(other)
         | 
| 259 | 
            +
                  other.is_a?(SearchAttributes) && @raw_hash == other._raw_hash
         | 
| 260 | 
            +
                end
         | 
| 261 | 
            +
             | 
| 221 262 | 
             
                alias size length
         | 
| 222 263 |  | 
| 223 264 | 
             
                # Return a new search attributes collection with updates applied.
         | 
| @@ -225,6 +266,7 @@ module Temporalio | |
| 225 266 | 
             
                # @param updates [Update] Updates created via {Key#value_set} or {Key#value_unset}.
         | 
| 226 267 | 
             
                # @return [SearchAttributes] New collection.
         | 
| 227 268 | 
             
                def update(*updates)
         | 
| 269 | 
            +
                  _assert_mutations_enabled
         | 
| 228 270 | 
             
                  attrs = dup
         | 
| 229 271 | 
             
                  attrs.update!(*updates)
         | 
| 230 272 | 
             
                  attrs
         | 
| @@ -234,27 +276,41 @@ module Temporalio | |
| 234 276 | 
             
                #
         | 
| 235 277 | 
             
                # @param updates [Update] Updates created via {Key#value_set} or {Key#value_unset}.
         | 
| 236 278 | 
             
                def update!(*updates)
         | 
| 279 | 
            +
                  _assert_mutations_enabled
         | 
| 237 280 | 
             
                  updates.each do |update|
         | 
| 238 281 | 
             
                    raise ArgumentError, 'Update must be an update' unless update.is_a?(Update)
         | 
| 239 282 |  | 
| 240 | 
            -
                     | 
| 283 | 
            +
                    if update.value.nil?
         | 
| 284 | 
            +
                      delete(update.key)
         | 
| 285 | 
            +
                    else
         | 
| 286 | 
            +
                      self[update.key] = update.value
         | 
| 287 | 
            +
                    end
         | 
| 241 288 | 
             
                  end
         | 
| 242 289 | 
             
                end
         | 
| 243 290 |  | 
| 244 291 | 
             
                # @!visibility private
         | 
| 245 | 
            -
                def  | 
| 246 | 
            -
                   | 
| 247 | 
            -
             | 
| 248 | 
            -
                      # We use a default converter, but if type is a time, we need ISO format
         | 
| 249 | 
            -
                      value = value.iso8601 if key.type == IndexedValueType::TIME
         | 
| 292 | 
            +
                def _raw_hash
         | 
| 293 | 
            +
                  @raw_hash
         | 
| 294 | 
            +
                end
         | 
| 250 295 |  | 
| 251 | 
            -
             | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 296 | 
            +
                # @!visibility private
         | 
| 297 | 
            +
                def _to_proto
         | 
| 298 | 
            +
                  Api::Common::V1::SearchAttributes.new(indexed_fields: _to_proto_hash)
         | 
| 299 | 
            +
                end
         | 
| 254 300 |  | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
                  )
         | 
| 301 | 
            +
                # @!visibility private
         | 
| 302 | 
            +
                def _to_proto_hash
         | 
| 303 | 
            +
                  @raw_hash.to_h { |key, value| SearchAttributes._to_proto_pair(key, value) }
         | 
| 304 | 
            +
                end
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                # @!visibility private
         | 
| 307 | 
            +
                def _assert_mutations_enabled
         | 
| 308 | 
            +
                  raise 'Search attribute mutations disabled' if @disable_mutations
         | 
| 309 | 
            +
                end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                # @!visibility private
         | 
| 312 | 
            +
                def _disable_mutations=(value)
         | 
| 313 | 
            +
                  @disable_mutations = value
         | 
| 258 314 | 
             
                end
         | 
| 259 315 |  | 
| 260 316 | 
             
                # Type for a search attribute key/value.
         |