activejob-temporal 0.2.0 → 0.3.1
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/CHANGELOG.md +16 -0
- data/activejob-temporal.gemspec +1 -1
- data/bin/temporal-worker +22 -9
- data/lib/activejob/temporal/certificate_watcher.rb +6 -1
- data/lib/activejob/temporal/client.rb +20 -3
- data/lib/activejob/temporal/configuration.rb +80 -1
- data/lib/activejob/temporal/locales/en.yml +15 -0
- data/lib/activejob/temporal/version.rb +1 -1
- data/lib/activejob/temporal/worker_registrations.rb +66 -0
- data/lib/activejob/temporal/worker_runtime.rb +1 -0
- data/lib/activejob/temporal.rb +19 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79166555209f6e6cf73641c9415feac14e6cffad299940c94ebcba0568c3cfdd
|
|
4
|
+
data.tar.gz: 4e3f843f44c93c4ce383415b32616f7770c407dec314dbf5e305a820e9095480
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f1dd16daf2739bbefdb568eb08423ca071fdc4ef96cee1b775d1fbb383728abec3c226d4f52d1ee633db6b7048ae5e6d68c0842a72dedf40cb03fdb4fe7d41ca
|
|
7
|
+
data.tar.gz: 9c17b2bf542f9990b68db645b32edd0176d8250309e70577d583f7d2102ed5cf176000ad5a5384a51c5ac4aa58fd18af161c226f389af413d66a0b00f01c84bd
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.1] - 2026-08-06
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `api_key_watch` and `tls_cert_watch` now fire on Kubernetes projected and secret volumes: kubelet rotates them atomically by swapping a `..data` symlink into a new timestamped directory, so the watched file's own path never appears in the change events and the previous exact-path filter dropped every rotation. Any change inside a watched file's directory now counts as relevant.
|
|
14
|
+
|
|
15
|
+
## [0.3.0] - 2026-08-06
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Bearer-token authentication: `api_key` (sent as the `Authorization: Bearer` header) and `api_key_file`, read through the same hardened path as TLS files — for example a projected Kubernetes ServiceAccount token. `api_key_watch` watches the token file and applies rotated tokens to the live connection via the new `ActiveJob::Temporal.refresh_api_key!` (no reconnect); enqueue-side processes using a rotating token file should call `refresh_api_key!` on their own schedule. `api_key` is redacted from `Configuration#inspect`. Caution: the Temporal SDK enables TLS when an API key is set and `tls` is nil — set `tls = false` explicitly for plaintext in-cluster servers (see the worker setup guide).
|
|
19
|
+
- Custom activity hosting: `worker_activities` registers additional activity classes (or class names) on the worker — for example activities invoked by workflows owned by another service, where only the activity name and JSON payloads travel over the wire. `worker_activejob_workloads = false` turns off the built-in ActiveJob workflows and activities for activities-only workers. Entries must be `Temporalio::Activity::Definition` subclasses; anything else fails worker startup with a `WorkerRegistrationError`.
|
|
20
|
+
- `graceful_shutdown_period` is passed to the Temporal worker, so a shutting-down worker lets running activities finish before their tasks are cancelled instead of cancelling them immediately.
|
|
21
|
+
- Configuration validation for the new attributes: `api_key_file` must be a readable regular file, `api_key_watch` requires `api_key_file`, disabling `worker_activejob_workloads` requires `worker_activities`, and `graceful_shutdown_period` must be >= 0.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- Allow temporalio 1.5 and 1.6 (dependency constraint is now `>= 1.4.0, < 1.7`); both added to the SDK contract-test matrix. Note for consumers upgrading within the range: temporalio 1.6 enables gzip gRPC transport compression by default — opt out with `grpc_compression` if an intermediary cannot handle it.
|
|
25
|
+
|
|
10
26
|
## [0.2.0] - 2026-08-06
|
|
11
27
|
|
|
12
28
|
### Security
|
data/activejob-temporal.gemspec
CHANGED
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
|
37
37
|
spec.add_dependency "activemodel", ">= 7.2", "< 9"
|
|
38
38
|
spec.add_dependency "concurrent-ruby", "~> 1.1"
|
|
39
39
|
spec.add_dependency "globalid", ">= 0.3"
|
|
40
|
-
spec.add_dependency "temporalio", ">= 1.4.0", "< 1.
|
|
40
|
+
spec.add_dependency "temporalio", ">= 1.4.0", "< 1.7"
|
|
41
41
|
|
|
42
42
|
spec.add_development_dependency "benchmark-ips", "~> 2.14"
|
|
43
43
|
spec.add_development_dependency "github_changelog_generator", "~> 1.18"
|
data/bin/temporal-worker
CHANGED
|
@@ -183,23 +183,24 @@ worker_health = ActiveJob::Temporal::WorkerHealth.new(
|
|
|
183
183
|
max_concurrent_workflows: max_concurrent_workflows
|
|
184
184
|
)
|
|
185
185
|
|
|
186
|
+
begin
|
|
187
|
+
registrations = ActiveJob::Temporal::WorkerRegistrations.resolve(config)
|
|
188
|
+
rescue ActiveJob::Temporal::WorkerRegistrationError => e
|
|
189
|
+
warn "Error: #{e.message}"
|
|
190
|
+
exit(1)
|
|
191
|
+
end
|
|
192
|
+
|
|
186
193
|
worker = Temporalio::Worker.new(
|
|
187
194
|
client: client,
|
|
188
195
|
task_queue: task_queue,
|
|
189
|
-
workflows:
|
|
190
|
-
|
|
191
|
-
ActiveJob::Temporal::Workflows::DeadLetterWorkflow
|
|
192
|
-
],
|
|
193
|
-
activities: [
|
|
194
|
-
ActiveJob::Temporal::Activities::RateLimitActivity,
|
|
195
|
-
ActiveJob::Temporal::Activities::DependencyStatusActivity,
|
|
196
|
-
ActiveJob::Temporal::Activities::AjRunnerActivity
|
|
197
|
-
],
|
|
196
|
+
workflows: registrations.workflows,
|
|
197
|
+
activities: registrations.activities,
|
|
198
198
|
tuner: Temporalio::Worker::Tuner.create_fixed(
|
|
199
199
|
workflow_slots: max_concurrent_workflows,
|
|
200
200
|
activity_slots: max_concurrent_activities,
|
|
201
201
|
local_activity_slots: max_concurrent_activities
|
|
202
202
|
),
|
|
203
|
+
graceful_shutdown_period: config.graceful_shutdown_period,
|
|
203
204
|
interceptors: [worker_health]
|
|
204
205
|
)
|
|
205
206
|
|
|
@@ -268,6 +269,17 @@ if config.tls_cert_watch
|
|
|
268
269
|
).start
|
|
269
270
|
end
|
|
270
271
|
|
|
272
|
+
# Token rotation mutates the live connection (the SDK sends the header per-RPC from the
|
|
273
|
+
# connection's stored options) - no client rebuild, unlike certificate rotation above.
|
|
274
|
+
# Configuration validation guarantees api_key_file is set when api_key_watch is on.
|
|
275
|
+
api_key_watcher = nil
|
|
276
|
+
if config.api_key_watch
|
|
277
|
+
api_key_watcher = ActiveJob::Temporal::CertificateWatcher.new(
|
|
278
|
+
paths: [config.api_key_file],
|
|
279
|
+
reload_callback: -> { ActiveJob::Temporal.refresh_api_key! }
|
|
280
|
+
).start
|
|
281
|
+
end
|
|
282
|
+
|
|
271
283
|
begin
|
|
272
284
|
worker_health.mark_started!
|
|
273
285
|
Temporalio::Worker.run_all(
|
|
@@ -279,6 +291,7 @@ rescue Interrupt
|
|
|
279
291
|
ensure
|
|
280
292
|
worker_health.mark_stopped!
|
|
281
293
|
certificate_watcher&.stop
|
|
294
|
+
api_key_watcher&.stop
|
|
282
295
|
reload_signal_queue.close
|
|
283
296
|
reload_signal_thread.join(1)
|
|
284
297
|
health_check_server&.stop
|
|
@@ -89,9 +89,14 @@ module ActiveJob
|
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
+
# Kubernetes projected and secret volumes rotate atomically: kubelet writes a new timestamped
|
|
93
|
+
# directory and swaps a `..data` symlink, so the watched file's own path never appears in the
|
|
94
|
+
# change events. Any change inside a watched file's directory therefore counts as relevant;
|
|
95
|
+
# the debounce absorbs the multi-event burst a rotation produces.
|
|
92
96
|
def relevant_change?(changed_paths)
|
|
93
97
|
changed_paths.any? do |path|
|
|
94
|
-
|
|
98
|
+
expanded = File.expand_path(path)
|
|
99
|
+
@paths.include?(expanded) || directories.any? { |dir| expanded.start_with?("#{dir}/") }
|
|
95
100
|
end
|
|
96
101
|
end
|
|
97
102
|
|
|
@@ -116,16 +116,33 @@ module ActiveJob
|
|
|
116
116
|
)
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
# Builds connection keyword arguments (
|
|
119
|
+
# Builds connection keyword arguments (TLS options and API key).
|
|
120
120
|
# @api private
|
|
121
121
|
def connection_kwargs(configuration)
|
|
122
|
+
kwargs = {}
|
|
123
|
+
|
|
122
124
|
tls = tls_options(configuration)
|
|
123
|
-
|
|
125
|
+
kwargs[:tls] = tls unless tls.nil?
|
|
126
|
+
|
|
127
|
+
api_key = resolve_api_key(configuration)
|
|
128
|
+
kwargs[:api_key] = api_key if api_key
|
|
124
129
|
|
|
125
|
-
|
|
130
|
+
kwargs
|
|
126
131
|
end
|
|
127
132
|
private_class_method :connection_kwargs
|
|
128
133
|
|
|
134
|
+
# Resolves the API key: an explicit api_key wins, otherwise api_key_file is read - at
|
|
135
|
+
# connection build time, and again by {ActiveJob::Temporal.refresh_api_key!} when the
|
|
136
|
+
# token file rotates.
|
|
137
|
+
# @api private
|
|
138
|
+
def resolve_api_key(configuration)
|
|
139
|
+
inline = configuration.api_key if configuration.respond_to?(:api_key)
|
|
140
|
+
return inline unless inline.nil? || inline.to_s.strip.empty?
|
|
141
|
+
|
|
142
|
+
path = configuration.api_key_file if configuration.respond_to?(:api_key_file)
|
|
143
|
+
read_tls_file(path)&.strip.presence
|
|
144
|
+
end
|
|
145
|
+
|
|
129
146
|
# Extracts TLS options from config or environment variables.
|
|
130
147
|
# @api private
|
|
131
148
|
def tls_options(configuration)
|
|
@@ -136,6 +136,29 @@ module ActiveJob
|
|
|
136
136
|
description: "Signal used by workers to reload TLS certificates manually"
|
|
137
137
|
},
|
|
138
138
|
|
|
139
|
+
api_key: {
|
|
140
|
+
default: nil,
|
|
141
|
+
env_var: "ACTIVEJOB_TEMPORAL_API_KEY",
|
|
142
|
+
type: :string,
|
|
143
|
+
description: "Optional API key sent as the Authorization bearer token"
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
api_key_file: {
|
|
147
|
+
default: nil,
|
|
148
|
+
env_var: "ACTIVEJOB_TEMPORAL_API_KEY_FILE",
|
|
149
|
+
type: :string,
|
|
150
|
+
description: "Optional file read for the API key when the client is built, for example a " \
|
|
151
|
+
"projected Kubernetes ServiceAccount token. An explicit api_key takes precedence"
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
api_key_watch: {
|
|
155
|
+
default: false,
|
|
156
|
+
env_var: "ACTIVEJOB_TEMPORAL_API_KEY_WATCH",
|
|
157
|
+
type: :boolean,
|
|
158
|
+
description: "Watch api_key_file and refresh the token when it changes (kubelet rotates " \
|
|
159
|
+
"projected tokens atomically, long before they expire)"
|
|
160
|
+
},
|
|
161
|
+
|
|
139
162
|
priority_task_queues: {
|
|
140
163
|
default: -> { {} },
|
|
141
164
|
type: :hash,
|
|
@@ -385,6 +408,29 @@ module ActiveJob
|
|
|
385
408
|
env_var: "ACTIVEJOB_TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS",
|
|
386
409
|
type: :integer,
|
|
387
410
|
description: "Maximum concurrent workflow tasks per worker"
|
|
411
|
+
},
|
|
412
|
+
|
|
413
|
+
worker_activities: {
|
|
414
|
+
default: -> { [] },
|
|
415
|
+
type: :array,
|
|
416
|
+
description: "Additional activity classes (or class names) the worker registers, for example " \
|
|
417
|
+
"activities invoked by workflows owned by another service"
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
worker_activejob_workloads: {
|
|
421
|
+
default: true,
|
|
422
|
+
env_var: "ACTIVEJOB_TEMPORAL_WORKER_ACTIVEJOB_WORKLOADS",
|
|
423
|
+
type: :boolean,
|
|
424
|
+
description: "Register the built-in ActiveJob workflows and activities on the worker. Disable " \
|
|
425
|
+
"for workers that only host worker_activities"
|
|
426
|
+
},
|
|
427
|
+
|
|
428
|
+
graceful_shutdown_period: {
|
|
429
|
+
default: 0.0,
|
|
430
|
+
env_var: "ACTIVEJOB_TEMPORAL_GRACEFUL_SHUTDOWN_PERIOD",
|
|
431
|
+
type: :float,
|
|
432
|
+
description: "Seconds a shutting-down worker lets running activities finish before their " \
|
|
433
|
+
"tasks are cancelled (0 cancels immediately, matching the SDK default)"
|
|
388
434
|
}
|
|
389
435
|
}.freeze
|
|
390
436
|
|
|
@@ -457,7 +503,7 @@ module ActiveJob
|
|
|
457
503
|
end
|
|
458
504
|
|
|
459
505
|
# Attributes holding secrets, redacted by {#inspect}.
|
|
460
|
-
REDACTED_ATTRIBUTES = %i[encryption_key encryption_old_keys tls].freeze
|
|
506
|
+
REDACTED_ATTRIBUTES = %i[encryption_key encryption_old_keys tls api_key].freeze
|
|
461
507
|
REDACTED_PLACEHOLDER = "[FILTERED]"
|
|
462
508
|
|
|
463
509
|
# Returns the configuration with secret attributes redacted.
|
|
@@ -661,6 +707,13 @@ module ActiveJob
|
|
|
661
707
|
allow_nil: false
|
|
662
708
|
}
|
|
663
709
|
|
|
710
|
+
validates :graceful_shutdown_period,
|
|
711
|
+
numericality: {
|
|
712
|
+
greater_than_or_equal_to: 0,
|
|
713
|
+
message: :graceful_shutdown_period_negative,
|
|
714
|
+
allow_nil: false
|
|
715
|
+
}
|
|
716
|
+
|
|
664
717
|
validates :continue_as_new_history_event_threshold,
|
|
665
718
|
numericality: {
|
|
666
719
|
greater_than: 0,
|
|
@@ -698,6 +751,8 @@ module ActiveJob
|
|
|
698
751
|
validate :validate_encryption_settings
|
|
699
752
|
validate :validate_payload_storage_settings
|
|
700
753
|
validate :validate_tls_settings
|
|
754
|
+
validate :validate_api_key_settings
|
|
755
|
+
validate :validate_worker_registration_settings
|
|
701
756
|
validate :validate_local_activity_helpers
|
|
702
757
|
validate :validate_dependency_wait_settings
|
|
703
758
|
|
|
@@ -1024,6 +1079,30 @@ module ActiveJob
|
|
|
1024
1079
|
errors.add(:tls_cert_watch, :requires_paths)
|
|
1025
1080
|
end
|
|
1026
1081
|
|
|
1082
|
+
def validate_api_key_settings
|
|
1083
|
+
validate_tls_file_path(:api_key_file)
|
|
1084
|
+
|
|
1085
|
+
unless [true, false].include?(api_key_watch)
|
|
1086
|
+
errors.add(:api_key_watch, :not_boolean, value: api_key_watch.inspect)
|
|
1087
|
+
return
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
return unless api_key_watch && api_key_file.to_s.strip.empty?
|
|
1091
|
+
|
|
1092
|
+
errors.add(:api_key_watch, :requires_path)
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
def validate_worker_registration_settings
|
|
1096
|
+
unless [true, false].include?(worker_activejob_workloads)
|
|
1097
|
+
errors.add(:worker_activejob_workloads, :not_boolean, value: worker_activejob_workloads.inspect)
|
|
1098
|
+
return
|
|
1099
|
+
end
|
|
1100
|
+
|
|
1101
|
+
return if worker_activejob_workloads || Array(worker_activities).any?
|
|
1102
|
+
|
|
1103
|
+
errors.add(:worker_activejob_workloads, :requires_activities)
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1027
1106
|
def validate_tls_reload_signal
|
|
1028
1107
|
unless tls_reload_signal.is_a?(String) && tls_reload_signal.strip.present?
|
|
1029
1108
|
errors.add(:tls_reload_signal, :blank)
|
|
@@ -136,3 +136,18 @@ en:
|
|
|
136
136
|
tls_reload_signal:
|
|
137
137
|
blank: "must be present when configured"
|
|
138
138
|
invalid: "must be a signal name like HUP or USR1, got: %{value}"
|
|
139
|
+
|
|
140
|
+
api_key_file:
|
|
141
|
+
invalid_path: "must be a non-empty file path, got: %{value}"
|
|
142
|
+
unreadable_path: "must resolve to a readable regular file, got: %{value}"
|
|
143
|
+
|
|
144
|
+
api_key_watch:
|
|
145
|
+
not_boolean: "must be true or false, got: %{value}"
|
|
146
|
+
requires_path: "requires api_key_file to watch"
|
|
147
|
+
|
|
148
|
+
worker_activejob_workloads:
|
|
149
|
+
not_boolean: "must be true or false, got: %{value}"
|
|
150
|
+
requires_activities: "requires worker_activities when disabled - the worker would have nothing to register"
|
|
151
|
+
|
|
152
|
+
graceful_shutdown_period:
|
|
153
|
+
graceful_shutdown_period_negative: "must be >= 0 seconds, got: %{value}"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "temporalio/activity"
|
|
4
|
+
|
|
5
|
+
module ActiveJob
|
|
6
|
+
module Temporal
|
|
7
|
+
# Resolves which workflows and activities a worker registers, from configuration.
|
|
8
|
+
#
|
|
9
|
+
# By default a worker hosts the built-in ActiveJob workloads. `worker_activities`
|
|
10
|
+
# adds custom activity classes - for example activities invoked by workflows owned
|
|
11
|
+
# by another service, where only the activity name and JSON payloads travel over
|
|
12
|
+
# the wire. Setting `worker_activejob_workloads = false` turns the worker into an
|
|
13
|
+
# activities-only worker that hosts nothing but those custom activities.
|
|
14
|
+
module WorkerRegistrations
|
|
15
|
+
Result = Struct.new(:workflows, :activities, keyword_init: true)
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
# Configuration validation rejects the nothing-to-register combination up front
|
|
19
|
+
# (see Configuration#validate_worker_registration_settings).
|
|
20
|
+
#
|
|
21
|
+
# @param configuration [ActiveJob::Temporal::Configuration]
|
|
22
|
+
# @return [Result] workflows and activities to pass to Temporalio::Worker
|
|
23
|
+
# @raise [WorkerRegistrationError] when a worker_activities entry does not resolve
|
|
24
|
+
# to a Temporalio::Activity::Definition subclass
|
|
25
|
+
def resolve(configuration)
|
|
26
|
+
workflows = []
|
|
27
|
+
activities = custom_activities(configuration)
|
|
28
|
+
|
|
29
|
+
if configuration.worker_activejob_workloads
|
|
30
|
+
workflows += [
|
|
31
|
+
Workflows::AjWorkflow,
|
|
32
|
+
Workflows::DeadLetterWorkflow
|
|
33
|
+
]
|
|
34
|
+
activities += [
|
|
35
|
+
Activities::RateLimitActivity,
|
|
36
|
+
Activities::DependencyStatusActivity,
|
|
37
|
+
Activities::AjRunnerActivity
|
|
38
|
+
]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Result.new(workflows: workflows, activities: activities)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def custom_activities(configuration)
|
|
47
|
+
Array(configuration.worker_activities).map { |entry| resolve_activity(entry) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def resolve_activity(entry)
|
|
51
|
+
activity = entry.is_a?(String) ? constantize_activity(entry) : entry
|
|
52
|
+
return activity if activity.is_a?(Class) && activity < Temporalio::Activity::Definition
|
|
53
|
+
|
|
54
|
+
raise WorkerRegistrationError,
|
|
55
|
+
"worker_activities entry #{entry.inspect} is not a Temporalio::Activity::Definition subclass"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def constantize_activity(name)
|
|
59
|
+
name.constantize
|
|
60
|
+
rescue NameError
|
|
61
|
+
raise WorkerRegistrationError, "worker_activities entry #{name.inspect} does not resolve to a class"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/activejob/temporal.rb
CHANGED
|
@@ -99,6 +99,11 @@ module ActiveJob
|
|
|
99
99
|
# @see Cancel.cancel
|
|
100
100
|
class TemporalConnectionError < Error; end
|
|
101
101
|
|
|
102
|
+
# Raised when a worker_activities entry cannot be used as a Temporal activity.
|
|
103
|
+
#
|
|
104
|
+
# @see WorkerRegistrations.resolve
|
|
105
|
+
class WorkerRegistrationError < Error; end
|
|
106
|
+
|
|
102
107
|
extend Configurable
|
|
103
108
|
|
|
104
109
|
class << self
|
|
@@ -157,6 +162,20 @@ module ActiveJob
|
|
|
157
162
|
fresh_client
|
|
158
163
|
end
|
|
159
164
|
|
|
165
|
+
# Re-reads the API key (api_key or api_key_file) and applies it to the memoized
|
|
166
|
+
# client's live connection. No reconnect happens - the SDK sends the header per-RPC
|
|
167
|
+
# from the connection's stored options. Worker processes call this from the
|
|
168
|
+
# api_key_watch file watcher; a long-lived enqueue-side process using a rotating
|
|
169
|
+
# token file must call it on its own schedule (nothing watches the file there).
|
|
170
|
+
#
|
|
171
|
+
# @return [String, nil] the freshly resolved API key
|
|
172
|
+
def refresh_api_key!
|
|
173
|
+
fresh_key = Client.resolve_api_key(config)
|
|
174
|
+
client.connection.api_key = fresh_key
|
|
175
|
+
Logger.log_event("api_key_refreshed")
|
|
176
|
+
fresh_key
|
|
177
|
+
end
|
|
178
|
+
|
|
160
179
|
# Cancels a running or scheduled job by job ID.
|
|
161
180
|
#
|
|
162
181
|
# This method requests cancellation for the Temporal workflow associated with the job.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activejob-temporal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Temporal Technologies
|
|
@@ -87,7 +87,7 @@ dependencies:
|
|
|
87
87
|
version: 1.4.0
|
|
88
88
|
- - "<"
|
|
89
89
|
- !ruby/object:Gem::Version
|
|
90
|
-
version: '1.
|
|
90
|
+
version: '1.7'
|
|
91
91
|
type: :runtime
|
|
92
92
|
prerelease: false
|
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -97,7 +97,7 @@ dependencies:
|
|
|
97
97
|
version: 1.4.0
|
|
98
98
|
- - "<"
|
|
99
99
|
- !ruby/object:Gem::Version
|
|
100
|
-
version: '1.
|
|
100
|
+
version: '1.7'
|
|
101
101
|
- !ruby/object:Gem::Dependency
|
|
102
102
|
name: benchmark-ips
|
|
103
103
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -371,6 +371,7 @@ files:
|
|
|
371
371
|
- lib/activejob/temporal/worker_client_reloader.rb
|
|
372
372
|
- lib/activejob/temporal/worker_health.rb
|
|
373
373
|
- lib/activejob/temporal/worker_pool.rb
|
|
374
|
+
- lib/activejob/temporal/worker_registrations.rb
|
|
374
375
|
- lib/activejob/temporal/worker_runtime.rb
|
|
375
376
|
- lib/activejob/temporal/workflow_enqueuer.rb
|
|
376
377
|
- lib/activejob/temporal/workflow_enqueuer_batch.rb
|