job-workflow 0.4.0 → 0.5.0
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 +10 -0
- data/README.md +1 -1
- data/guides/API_REFERENCE.md +70 -0
- data/guides/PRODUCTION_DEPLOYMENT.md +1 -1
- data/guides/README.md +1 -1
- data/lib/job_workflow/context.rb +61 -1
- data/lib/job_workflow/dsl.rb +1 -1
- data/lib/job_workflow/railtie.rb +10 -0
- data/lib/job_workflow/runner.rb +33 -12
- data/lib/job_workflow/task.rb +7 -0
- data/lib/job_workflow/version.rb +1 -1
- data/lib/job_workflow.rb +3 -1
- data/sig/generated/job_workflow/context.rbs +24 -0
- data/sig/generated/job_workflow/railtie.rbs +6 -0
- data/sig/generated/job_workflow/runner.rbs +7 -4
- data/sig/generated/job_workflow/task.rbs +5 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9474c65583cf21d485c3468675d4f23124e60e88f98c954bd38256b916d98ffe
|
|
4
|
+
data.tar.gz: 59d5e0b60a2b52e87ea4da4aab1834d02c63f88cba36f661acd8c74f89a4e6a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ac034e1b373b28aa52dcffd059bc5b64e5c45fc04d9b07460c24491c2514eabddf839b2dcb2c4a2cfbf36b578e2836e153e9bd6f34cd24f8af543cf06242ce9
|
|
7
|
+
data.tar.gz: 455b6913137103b6a5871562a6adc0ffca11e9e99543b94ec7e0bda9f2b78c6c76c5cee73baec30ca5b5b5e2fd388d6a4b119c08d7cf1039c20e115e255f58d7
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.5.0] - 2026-05-13
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Add task-scoped cursor helpers on `Context` so tasks can persist progress, restore task-local continuation state, and delegate explicit checkpoints without exposing ActiveJob continuation internals
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Initialize the SolidQueue adapter from a Railtie after Rails boot so the `ClaimedExecution` patch is applied reliably, rescheduled `dependency_wait` jobs are not marked finished early, and Rails apps no longer need a manual initializer
|
|
12
|
+
|
|
3
13
|
## [0.4.0] - 2026-05-12
|
|
4
14
|
|
|
5
15
|
### Fixed
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# JobWorkflow
|
|
2
2
|
|
|
3
|
-
> ⚠️ **Early Stage (v0.
|
|
3
|
+
> ⚠️ **Early Stage (v0.5.0):** This library is in active development. APIs and features may change in breaking ways without notice. Use in production at your own risk and expect potential breaking changes in future releases.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
data/guides/API_REFERENCE.md
CHANGED
|
@@ -84,6 +84,76 @@ end
|
|
|
84
84
|
|
|
85
85
|
**Map Task Output**: When `each:` is specified, outputs are automatically collected as an array.
|
|
86
86
|
|
|
87
|
+
### Task continuation helpers
|
|
88
|
+
|
|
89
|
+
Inside a task body, you can read the current task cursor, store a new cursor, and create interruption points through the task context.
|
|
90
|
+
|
|
91
|
+
#### Regular task example
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
task :sync_pages, output: { processed: "Integer" } do |ctx|
|
|
95
|
+
page = ctx.cursor || 1
|
|
96
|
+
result = ExternalAPI.fetch(page:)
|
|
97
|
+
|
|
98
|
+
ctx.set_cursor!(page + 1) if result.next_page?
|
|
99
|
+
|
|
100
|
+
{ processed: result.items.size }
|
|
101
|
+
end
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- `ctx.cursor` returns the current task cursor, or `nil` when no cursor has been stored
|
|
105
|
+
- `ctx.set_cursor!(value)` validates that `value` is ActiveJob-serializable, stores it in the current continuation step, and checkpoints the job through Active Job continuation
|
|
106
|
+
- `ctx.checkpoint!` creates a checkpoint without changing the public cursor value
|
|
107
|
+
- Call `ctx.set_cursor!` when you want to change the public cursor value and create a checkpoint at the same time
|
|
108
|
+
- Call `ctx.checkpoint!` when you want the current task execution to become interruptible without changing the public cursor value
|
|
109
|
+
- Outside task execution, `ctx.cursor` returns `nil`, and `ctx.set_cursor!` / `ctx.checkpoint!` raise an error
|
|
110
|
+
|
|
111
|
+
For regular tasks, a cursor is only persisted when you call `ctx.set_cursor!(value)` explicitly.
|
|
112
|
+
|
|
113
|
+
#### Checkpoint without changing the cursor
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
task :publish_report do |ctx|
|
|
117
|
+
report = build_report
|
|
118
|
+
ctx.checkpoint!
|
|
119
|
+
deliver_report(report)
|
|
120
|
+
end
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Repeating work inside a task
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
task :sync_users do |ctx|
|
|
127
|
+
start_index = ctx.cursor || 0
|
|
128
|
+
|
|
129
|
+
ctx.arguments.user_ids.drop(start_index).each_with_index do |user_id, offset|
|
|
130
|
+
sync_user(user_id)
|
|
131
|
+
ctx.set_cursor!(start_index + offset + 1)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This pattern is useful when a single task iterates over an Enumerable internally and you want to resume from the last completed item after an interruption.
|
|
137
|
+
|
|
138
|
+
#### `each:` task example
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
task :sync_users, each: ->(ctx) { ctx.arguments.user_ids } do |ctx|
|
|
142
|
+
next_cursor = ExternalAPI.sync_user(
|
|
143
|
+
user_id: ctx.each_value,
|
|
144
|
+
cursor: ctx.cursor
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
ctx.set_cursor!(next_cursor) unless next_cursor.nil?
|
|
148
|
+
end
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For `each:` tasks, JobWorkflow keeps the existing integer resume behavior for completed iterations.
|
|
152
|
+
|
|
153
|
+
- If an `each:` task is interrupted after calling `ctx.set_cursor!`, JobWorkflow resumes with both the current iteration index and the saved task cursor
|
|
154
|
+
- If an iteration completes normally, the resume state advances to the next integer index
|
|
155
|
+
- In other words, a custom cursor in an `each:` task is meant for resuming work inside the current iteration, not for replacing the completion index of finished iterations
|
|
156
|
+
|
|
87
157
|
### workflow_concurrency
|
|
88
158
|
|
|
89
159
|
Configure job-level concurrency limits with workflow-aware context.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Production Deployment
|
|
2
2
|
|
|
3
|
-
> ⚠️ **Early Stage (v0.
|
|
3
|
+
> ⚠️ **Early Stage (v0.5.0):** JobWorkflow is still in early development. While this section outlines potential deployment patterns, please thoroughly test in your specific environment and monitor for any issues before relying on JobWorkflow in critical production systems.
|
|
4
4
|
|
|
5
5
|
This section covers suggested settings and patterns for running JobWorkflow in production-like environments.
|
|
6
6
|
|
data/guides/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# JobWorkflow Guides
|
|
2
2
|
|
|
3
|
-
> ⚠️ **Early Stage (v0.
|
|
3
|
+
> ⚠️ **Early Stage (v0.5.0):** JobWorkflow is in active development. APIs and features may change. The following guides provide patterns and examples for building workflows, but be aware that implementations may need adjustment as the library evolves.
|
|
4
4
|
|
|
5
5
|
Welcome to the JobWorkflow documentation! This directory contains comprehensive guides to help you build robust workflows with JobWorkflow.
|
|
6
6
|
|
data/lib/job_workflow/context.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module JobWorkflow
|
|
4
4
|
class Context # rubocop:disable Metrics/ClassLength
|
|
5
|
+
EACH_TASK_CURSOR_MARKER = "__job_workflow_each_cursor__"
|
|
6
|
+
|
|
5
7
|
attr_reader :workflow #: Workflow
|
|
6
8
|
attr_reader :arguments #: Arguments
|
|
7
9
|
attr_reader :output #: Output
|
|
@@ -52,7 +54,7 @@ module JobWorkflow
|
|
|
52
54
|
# job_status: JobStatus,
|
|
53
55
|
# ?job: DSL?
|
|
54
56
|
# ) -> void
|
|
55
|
-
def initialize(workflow:, arguments:, task_context:, output:, job_status:, job: nil) # rubocop:disable Metrics/ParameterLists
|
|
57
|
+
def initialize(workflow:, arguments:, task_context:, output:, job_status:, job: nil) # rubocop:disable Metrics/ParameterLists, Metrics/AbcSize, Metrics/MethodLength
|
|
56
58
|
raise "job does not match the provided workflow" if job&.then { |j| j.class._workflow != workflow }
|
|
57
59
|
|
|
58
60
|
self.job = job
|
|
@@ -64,6 +66,8 @@ module JobWorkflow
|
|
|
64
66
|
self.enabled_with_each_value = false
|
|
65
67
|
self.throttle_index = 0
|
|
66
68
|
self.skip_in_dry_run_index = 0
|
|
69
|
+
self.current_step = nil
|
|
70
|
+
self.current_cursor = nil
|
|
67
71
|
end
|
|
68
72
|
|
|
69
73
|
#: () -> Hash[String, untyped]
|
|
@@ -77,6 +81,31 @@ module JobWorkflow
|
|
|
77
81
|
self
|
|
78
82
|
end
|
|
79
83
|
|
|
84
|
+
#: () -> untyped
|
|
85
|
+
def cursor
|
|
86
|
+
return if current_step.nil?
|
|
87
|
+
|
|
88
|
+
current_cursor
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
#: (untyped) -> void
|
|
92
|
+
def set_cursor!(value)
|
|
93
|
+
step = current_step || (raise "set_cursor! can be called only in task")
|
|
94
|
+
|
|
95
|
+
ActiveJob::Arguments.serialize([value])
|
|
96
|
+
self.current_cursor = value
|
|
97
|
+
step.set!(build_step_cursor(value))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#: () -> void
|
|
101
|
+
def checkpoint!
|
|
102
|
+
step = current_step || (raise "checkpoint! can be called only in task")
|
|
103
|
+
|
|
104
|
+
return step.checkpoint! unless each_task?
|
|
105
|
+
|
|
106
|
+
step.set!(build_step_cursor(current_cursor))
|
|
107
|
+
end
|
|
108
|
+
|
|
80
109
|
#: (DSL) -> void
|
|
81
110
|
def _job=(job)
|
|
82
111
|
self.job = job
|
|
@@ -220,6 +249,18 @@ module JobWorkflow
|
|
|
220
249
|
task_context
|
|
221
250
|
end
|
|
222
251
|
|
|
252
|
+
#: (ActiveJob::Continuation::Step, ?cursor: untyped) { () -> void } -> void
|
|
253
|
+
def _with_current_step(step, cursor: nil)
|
|
254
|
+
previous_step = current_step
|
|
255
|
+
previous_cursor = current_cursor
|
|
256
|
+
self.current_step = step
|
|
257
|
+
self.current_cursor = cursor
|
|
258
|
+
yield
|
|
259
|
+
ensure
|
|
260
|
+
self.current_step = previous_step
|
|
261
|
+
self.current_cursor = previous_cursor
|
|
262
|
+
end
|
|
263
|
+
|
|
223
264
|
#: (TaskOutput) -> void
|
|
224
265
|
def _add_task_output(task_output)
|
|
225
266
|
output.add_task_output(task_output)
|
|
@@ -245,12 +286,31 @@ module JobWorkflow
|
|
|
245
286
|
attr_accessor :enabled_with_each_value #: bool
|
|
246
287
|
attr_accessor :throttle_index #: Integer
|
|
247
288
|
attr_accessor :skip_in_dry_run_index #: Integer
|
|
289
|
+
attr_accessor :current_step #: ActiveJob::Continuation::Step?
|
|
290
|
+
attr_accessor :current_cursor #: untyped
|
|
248
291
|
|
|
249
292
|
#: () -> String
|
|
250
293
|
def parent_job_id
|
|
251
294
|
_task_context.parent_job_id || job_id
|
|
252
295
|
end
|
|
253
296
|
|
|
297
|
+
#: () -> bool
|
|
298
|
+
def each_task?
|
|
299
|
+
task_context.task.each?
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
#: (untyped) -> untyped
|
|
303
|
+
def build_step_cursor(value)
|
|
304
|
+
return value unless each_task?
|
|
305
|
+
return task_context.index if value.nil?
|
|
306
|
+
|
|
307
|
+
{
|
|
308
|
+
EACH_TASK_CURSOR_MARKER => true,
|
|
309
|
+
"index" => task_context.index,
|
|
310
|
+
"cursor" => value
|
|
311
|
+
}
|
|
312
|
+
end
|
|
313
|
+
|
|
254
314
|
#: () -> Hash[String, untyped]
|
|
255
315
|
def serialize_for_job
|
|
256
316
|
{
|
data/lib/job_workflow/dsl.rb
CHANGED
data/lib/job_workflow/runner.rb
CHANGED
|
@@ -14,7 +14,7 @@ module JobWorkflow
|
|
|
14
14
|
def run
|
|
15
15
|
task = context._task_context.task
|
|
16
16
|
if !task.nil? && context.sub_job?
|
|
17
|
-
run_task(task)
|
|
17
|
+
job.step(task.task_name) { |step| run_task(task, step:) }
|
|
18
18
|
persist_current_job_context
|
|
19
19
|
return
|
|
20
20
|
end
|
|
@@ -63,25 +63,46 @@ module JobWorkflow
|
|
|
63
63
|
result
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
#: (Task,
|
|
67
|
-
def run_task(task, step:
|
|
66
|
+
#: (Task, step: ActiveJob::Continuation::Step) -> void
|
|
67
|
+
def run_task(task, step:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
68
68
|
context._load_parent_task_output
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
start_index, task_cursor = decode_task_cursor(task, step.cursor)
|
|
70
|
+
|
|
71
|
+
context._with_each_value(task, start_index:).each do |ctx|
|
|
72
|
+
iteration_cursor = task_cursor
|
|
73
|
+
iteration_cursor = nil if task.each? && (task_cursor.nil? || start_index != ctx._task_context.index)
|
|
74
|
+
|
|
75
|
+
run_each_task(task, ctx, step:, cursor: iteration_cursor)
|
|
76
|
+
step.set!(ctx._task_context.index + 1) if task.each?
|
|
72
77
|
rescue StandardError => e
|
|
73
78
|
run_error_hooks(task, ctx, e)
|
|
74
79
|
raise
|
|
75
80
|
end
|
|
76
81
|
end
|
|
77
82
|
|
|
78
|
-
#: (Task,
|
|
79
|
-
def
|
|
83
|
+
#: (Task, untyped) -> [Integer?, untyped]
|
|
84
|
+
def decode_task_cursor(task, task_cursor)
|
|
85
|
+
return [nil, task_cursor] unless task.each?
|
|
86
|
+
return [task_cursor, nil] if task_cursor.is_a?(Integer)
|
|
87
|
+
|
|
88
|
+
if task_cursor.is_a?(Hash) && task_cursor[Context::EACH_TASK_CURSOR_MARKER]
|
|
89
|
+
return [task_cursor.fetch("index"), task_cursor.fetch("cursor")]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
raise "invalid each task cursor: #{task_cursor.inspect}" unless task_cursor.nil?
|
|
93
|
+
|
|
94
|
+
[nil, nil]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
#: (Task, Context, step: ActiveJob::Continuation::Step, ?cursor: untyped) -> void
|
|
98
|
+
def run_each_task(task, ctx, step:, cursor: nil)
|
|
80
99
|
Instrumentation.instrument_task(job, task, ctx) do
|
|
81
|
-
ctx.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
ctx._with_current_step(step, cursor:) do
|
|
101
|
+
ctx._with_task_throttle do
|
|
102
|
+
run_hooks(task, ctx) do
|
|
103
|
+
data = task.block.call(ctx)
|
|
104
|
+
add_task_output(ctx:, task:, each_index: ctx._task_context.index, data:)
|
|
105
|
+
end
|
|
85
106
|
end
|
|
86
107
|
end
|
|
87
108
|
end
|
data/lib/job_workflow/task.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module JobWorkflow
|
|
4
4
|
class Task
|
|
5
|
+
DEFAULT_EACH = ->(_ctx) { [nil] }
|
|
6
|
+
|
|
5
7
|
attr_reader :job_name #: String
|
|
6
8
|
attr_reader :block #: ^(untyped) -> void
|
|
7
9
|
attr_reader :each #: ^(Context) -> untyped
|
|
@@ -72,6 +74,11 @@ module JobWorkflow
|
|
|
72
74
|
"#{job_name}:#{task_name}"
|
|
73
75
|
end
|
|
74
76
|
|
|
77
|
+
#: () -> bool
|
|
78
|
+
def each?
|
|
79
|
+
!each.nil? && !each.equal?(DEFAULT_EACH)
|
|
80
|
+
end
|
|
81
|
+
|
|
75
82
|
private
|
|
76
83
|
|
|
77
84
|
attr_reader :name #: Symbol
|
data/lib/job_workflow/version.rb
CHANGED
data/lib/job_workflow.rb
CHANGED
|
@@ -45,6 +45,9 @@ require_relative "job_workflow/task_output"
|
|
|
45
45
|
require_relative "job_workflow/output"
|
|
46
46
|
require_relative "job_workflow/queue"
|
|
47
47
|
require_relative "job_workflow/auto_scaling"
|
|
48
|
+
# :nocov:
|
|
49
|
+
require_relative "job_workflow/railtie" if defined?(Rails::Railtie)
|
|
50
|
+
# :nocov:
|
|
48
51
|
|
|
49
52
|
module JobWorkflow
|
|
50
53
|
class Error < StandardError; end
|
|
@@ -53,6 +56,5 @@ module JobWorkflow
|
|
|
53
56
|
|
|
54
57
|
Instrumentation::LogSubscriber.attach!
|
|
55
58
|
|
|
56
|
-
ActiveSupport.on_load(:solid_queue) { QueueAdapter.current.initialize_adapter! }
|
|
57
59
|
QueueAdapter.current.initialize_adapter!
|
|
58
60
|
end
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module JobWorkflow
|
|
4
4
|
class Context
|
|
5
5
|
# rubocop:disable Metrics/ClassLength
|
|
6
|
+
EACH_TASK_CURSOR_MARKER: ::String
|
|
7
|
+
|
|
6
8
|
attr_reader workflow: Workflow
|
|
7
9
|
|
|
8
10
|
attr_reader arguments: Arguments
|
|
@@ -33,6 +35,15 @@ module JobWorkflow
|
|
|
33
35
|
# : (Hash[Symbol, untyped]) -> Context
|
|
34
36
|
def _update_arguments: (Hash[Symbol, untyped]) -> Context
|
|
35
37
|
|
|
38
|
+
# : () -> untyped
|
|
39
|
+
def cursor: () -> untyped
|
|
40
|
+
|
|
41
|
+
# : (untyped) -> void
|
|
42
|
+
def set_cursor!: (untyped) -> void
|
|
43
|
+
|
|
44
|
+
# : () -> void
|
|
45
|
+
def checkpoint!: () -> void
|
|
46
|
+
|
|
36
47
|
# : (DSL) -> void
|
|
37
48
|
def _job=: (DSL) -> void
|
|
38
49
|
|
|
@@ -93,6 +104,9 @@ module JobWorkflow
|
|
|
93
104
|
# : () -> TaskContext
|
|
94
105
|
def _task_context: () -> TaskContext
|
|
95
106
|
|
|
107
|
+
# : (ActiveJob::Continuation::Step, ?cursor: untyped) { () -> void } -> void
|
|
108
|
+
def _with_current_step: (ActiveJob::Continuation::Step, ?cursor: untyped) { () -> void } -> void
|
|
109
|
+
|
|
96
110
|
# : (TaskOutput) -> void
|
|
97
111
|
def _add_task_output: (TaskOutput) -> void
|
|
98
112
|
|
|
@@ -119,9 +133,19 @@ module JobWorkflow
|
|
|
119
133
|
|
|
120
134
|
attr_accessor skip_in_dry_run_index: Integer
|
|
121
135
|
|
|
136
|
+
attr_accessor current_step: ActiveJob::Continuation::Step?
|
|
137
|
+
|
|
138
|
+
attr_accessor current_cursor: untyped
|
|
139
|
+
|
|
122
140
|
# : () -> String
|
|
123
141
|
def parent_job_id: () -> String
|
|
124
142
|
|
|
143
|
+
# : () -> bool
|
|
144
|
+
def each_task?: () -> bool
|
|
145
|
+
|
|
146
|
+
# : (untyped) -> untyped
|
|
147
|
+
def build_step_cursor: (untyped) -> untyped
|
|
148
|
+
|
|
125
149
|
# : () -> Hash[String, untyped]
|
|
126
150
|
def serialize_for_job: () -> Hash[String, untyped]
|
|
127
151
|
|
|
@@ -30,11 +30,14 @@ module JobWorkflow
|
|
|
30
30
|
# : (Task) -> bool
|
|
31
31
|
def skip_task?: (Task) -> bool
|
|
32
32
|
|
|
33
|
-
# : (Task,
|
|
34
|
-
def run_task: (Task,
|
|
33
|
+
# : (Task, step: ActiveJob::Continuation::Step) -> void
|
|
34
|
+
def run_task: (Task, step: ActiveJob::Continuation::Step) -> void
|
|
35
35
|
|
|
36
|
-
# : (Task,
|
|
37
|
-
def
|
|
36
|
+
# : (Task, untyped) -> [Integer?, untyped]
|
|
37
|
+
def decode_task_cursor: (Task, untyped) -> [ Integer?, untyped ]
|
|
38
|
+
|
|
39
|
+
# : (Task, Context, step: ActiveJob::Continuation::Step, ?cursor: untyped) -> void
|
|
40
|
+
def run_each_task: (Task, Context, step: ActiveJob::Continuation::Step, ?cursor: untyped) -> void
|
|
38
41
|
|
|
39
42
|
# : (Task, Context) { () -> void } -> void
|
|
40
43
|
def run_hooks: (Task, Context) { () -> void } -> void
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module JobWorkflow
|
|
4
4
|
class Task
|
|
5
|
+
DEFAULT_EACH: untyped
|
|
6
|
+
|
|
5
7
|
attr_reader job_name: String
|
|
6
8
|
|
|
7
9
|
attr_reader block: ^(untyped) -> void
|
|
@@ -50,6 +52,9 @@ module JobWorkflow
|
|
|
50
52
|
# : () -> String
|
|
51
53
|
def throttle_prefix_key: () -> String
|
|
52
54
|
|
|
55
|
+
# : () -> bool
|
|
56
|
+
def each?: () -> bool
|
|
57
|
+
|
|
53
58
|
private
|
|
54
59
|
|
|
55
60
|
attr_reader name: Symbol
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: job-workflow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- shoma07
|
|
@@ -90,6 +90,7 @@ files:
|
|
|
90
90
|
- lib/job_workflow/queue_adapters/abstract.rb
|
|
91
91
|
- lib/job_workflow/queue_adapters/null_adapter.rb
|
|
92
92
|
- lib/job_workflow/queue_adapters/solid_queue_adapter.rb
|
|
93
|
+
- lib/job_workflow/railtie.rb
|
|
93
94
|
- lib/job_workflow/runner.rb
|
|
94
95
|
- lib/job_workflow/schedule.rb
|
|
95
96
|
- lib/job_workflow/semaphore.rb
|
|
@@ -141,6 +142,7 @@ files:
|
|
|
141
142
|
- sig/generated/job_workflow/queue_adapters/abstract.rbs
|
|
142
143
|
- sig/generated/job_workflow/queue_adapters/null_adapter.rbs
|
|
143
144
|
- sig/generated/job_workflow/queue_adapters/solid_queue_adapter.rbs
|
|
145
|
+
- sig/generated/job_workflow/railtie.rbs
|
|
144
146
|
- sig/generated/job_workflow/runner.rbs
|
|
145
147
|
- sig/generated/job_workflow/schedule.rbs
|
|
146
148
|
- sig/generated/job_workflow/semaphore.rbs
|