job-workflow 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +91 -0
  4. data/CHANGELOG.md +23 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +47 -0
  7. data/Rakefile +55 -0
  8. data/Steepfile +10 -0
  9. data/guides/API_REFERENCE.md +112 -0
  10. data/guides/BEST_PRACTICES.md +113 -0
  11. data/guides/CACHE_STORE_INTEGRATION.md +145 -0
  12. data/guides/CONDITIONAL_EXECUTION.md +66 -0
  13. data/guides/DEPENDENCY_WAIT.md +386 -0
  14. data/guides/DRY_RUN.md +390 -0
  15. data/guides/DSL_BASICS.md +216 -0
  16. data/guides/ERROR_HANDLING.md +187 -0
  17. data/guides/GETTING_STARTED.md +524 -0
  18. data/guides/INSTRUMENTATION.md +131 -0
  19. data/guides/LIFECYCLE_HOOKS.md +415 -0
  20. data/guides/NAMESPACES.md +75 -0
  21. data/guides/OPENTELEMETRY_INTEGRATION.md +86 -0
  22. data/guides/PARALLEL_PROCESSING.md +302 -0
  23. data/guides/PRODUCTION_DEPLOYMENT.md +110 -0
  24. data/guides/QUEUE_MANAGEMENT.md +141 -0
  25. data/guides/README.md +174 -0
  26. data/guides/SCHEDULED_JOBS.md +165 -0
  27. data/guides/STRUCTURED_LOGGING.md +268 -0
  28. data/guides/TASK_OUTPUTS.md +240 -0
  29. data/guides/TESTING_STRATEGY.md +56 -0
  30. data/guides/THROTTLING.md +198 -0
  31. data/guides/TROUBLESHOOTING.md +53 -0
  32. data/guides/WORKFLOW_COMPOSITION.md +675 -0
  33. data/guides/WORKFLOW_STATUS_QUERY.md +288 -0
  34. data/lib/job-workflow.rb +3 -0
  35. data/lib/job_workflow/argument_def.rb +16 -0
  36. data/lib/job_workflow/arguments.rb +40 -0
  37. data/lib/job_workflow/auto_scaling/adapter/aws_adapter.rb +66 -0
  38. data/lib/job_workflow/auto_scaling/adapter.rb +31 -0
  39. data/lib/job_workflow/auto_scaling/configuration.rb +85 -0
  40. data/lib/job_workflow/auto_scaling/executor.rb +43 -0
  41. data/lib/job_workflow/auto_scaling.rb +69 -0
  42. data/lib/job_workflow/cache_store_adapters.rb +46 -0
  43. data/lib/job_workflow/context.rb +352 -0
  44. data/lib/job_workflow/dry_run_config.rb +31 -0
  45. data/lib/job_workflow/dsl.rb +236 -0
  46. data/lib/job_workflow/error_hook.rb +24 -0
  47. data/lib/job_workflow/hook.rb +24 -0
  48. data/lib/job_workflow/hook_registry.rb +66 -0
  49. data/lib/job_workflow/instrumentation/log_subscriber.rb +194 -0
  50. data/lib/job_workflow/instrumentation/opentelemetry_subscriber.rb +221 -0
  51. data/lib/job_workflow/instrumentation.rb +257 -0
  52. data/lib/job_workflow/job_status.rb +92 -0
  53. data/lib/job_workflow/logger.rb +86 -0
  54. data/lib/job_workflow/namespace.rb +36 -0
  55. data/lib/job_workflow/output.rb +81 -0
  56. data/lib/job_workflow/output_def.rb +14 -0
  57. data/lib/job_workflow/queue.rb +74 -0
  58. data/lib/job_workflow/queue_adapter.rb +38 -0
  59. data/lib/job_workflow/queue_adapters/abstract.rb +87 -0
  60. data/lib/job_workflow/queue_adapters/null_adapter.rb +127 -0
  61. data/lib/job_workflow/queue_adapters/solid_queue_adapter.rb +224 -0
  62. data/lib/job_workflow/runner.rb +173 -0
  63. data/lib/job_workflow/schedule.rb +46 -0
  64. data/lib/job_workflow/semaphore.rb +71 -0
  65. data/lib/job_workflow/task.rb +83 -0
  66. data/lib/job_workflow/task_callable.rb +43 -0
  67. data/lib/job_workflow/task_context.rb +70 -0
  68. data/lib/job_workflow/task_dependency_wait.rb +66 -0
  69. data/lib/job_workflow/task_enqueue.rb +50 -0
  70. data/lib/job_workflow/task_graph.rb +43 -0
  71. data/lib/job_workflow/task_job_status.rb +70 -0
  72. data/lib/job_workflow/task_output.rb +51 -0
  73. data/lib/job_workflow/task_retry.rb +64 -0
  74. data/lib/job_workflow/task_throttle.rb +46 -0
  75. data/lib/job_workflow/version.rb +5 -0
  76. data/lib/job_workflow/workflow.rb +87 -0
  77. data/lib/job_workflow/workflow_status.rb +112 -0
  78. data/lib/job_workflow.rb +59 -0
  79. data/rbs_collection.lock.yaml +172 -0
  80. data/rbs_collection.yaml +14 -0
  81. data/sig/generated/job-workflow.rbs +2 -0
  82. data/sig/generated/job_workflow/argument_def.rbs +14 -0
  83. data/sig/generated/job_workflow/arguments.rbs +26 -0
  84. data/sig/generated/job_workflow/auto_scaling/adapter/aws_adapter.rbs +32 -0
  85. data/sig/generated/job_workflow/auto_scaling/adapter.rbs +22 -0
  86. data/sig/generated/job_workflow/auto_scaling/configuration.rbs +50 -0
  87. data/sig/generated/job_workflow/auto_scaling/executor.rbs +29 -0
  88. data/sig/generated/job_workflow/auto_scaling.rbs +47 -0
  89. data/sig/generated/job_workflow/cache_store_adapters.rbs +28 -0
  90. data/sig/generated/job_workflow/context.rbs +155 -0
  91. data/sig/generated/job_workflow/dry_run_config.rbs +16 -0
  92. data/sig/generated/job_workflow/dsl.rbs +117 -0
  93. data/sig/generated/job_workflow/error_hook.rbs +18 -0
  94. data/sig/generated/job_workflow/hook.rbs +18 -0
  95. data/sig/generated/job_workflow/hook_registry.rbs +47 -0
  96. data/sig/generated/job_workflow/instrumentation/log_subscriber.rbs +102 -0
  97. data/sig/generated/job_workflow/instrumentation/opentelemetry_subscriber.rbs +113 -0
  98. data/sig/generated/job_workflow/instrumentation.rbs +138 -0
  99. data/sig/generated/job_workflow/job_status.rbs +46 -0
  100. data/sig/generated/job_workflow/logger.rbs +56 -0
  101. data/sig/generated/job_workflow/namespace.rbs +24 -0
  102. data/sig/generated/job_workflow/output.rbs +39 -0
  103. data/sig/generated/job_workflow/output_def.rbs +12 -0
  104. data/sig/generated/job_workflow/queue.rbs +49 -0
  105. data/sig/generated/job_workflow/queue_adapter.rbs +18 -0
  106. data/sig/generated/job_workflow/queue_adapters/abstract.rbs +56 -0
  107. data/sig/generated/job_workflow/queue_adapters/null_adapter.rbs +73 -0
  108. data/sig/generated/job_workflow/queue_adapters/solid_queue_adapter.rbs +111 -0
  109. data/sig/generated/job_workflow/runner.rbs +66 -0
  110. data/sig/generated/job_workflow/schedule.rbs +34 -0
  111. data/sig/generated/job_workflow/semaphore.rbs +37 -0
  112. data/sig/generated/job_workflow/task.rbs +60 -0
  113. data/sig/generated/job_workflow/task_callable.rbs +30 -0
  114. data/sig/generated/job_workflow/task_context.rbs +52 -0
  115. data/sig/generated/job_workflow/task_dependency_wait.rbs +42 -0
  116. data/sig/generated/job_workflow/task_enqueue.rbs +27 -0
  117. data/sig/generated/job_workflow/task_graph.rbs +27 -0
  118. data/sig/generated/job_workflow/task_job_status.rbs +42 -0
  119. data/sig/generated/job_workflow/task_output.rbs +29 -0
  120. data/sig/generated/job_workflow/task_retry.rbs +30 -0
  121. data/sig/generated/job_workflow/task_throttle.rbs +20 -0
  122. data/sig/generated/job_workflow/version.rbs +5 -0
  123. data/sig/generated/job_workflow/workflow.rbs +48 -0
  124. data/sig/generated/job_workflow/workflow_status.rbs +55 -0
  125. data/sig/generated/job_workflow.rbs +8 -0
  126. data/sig-private/activejob.rbs +35 -0
  127. data/sig-private/activesupport.rbs +23 -0
  128. data/sig-private/aws.rbs +32 -0
  129. data/sig-private/opentelemetry.rbs +40 -0
  130. data/sig-private/solid_queue.rbs +108 -0
  131. data/tmp/.keep +0 -0
  132. metadata +190 -0
@@ -0,0 +1,28 @@
1
+ # Generated from lib/job_workflow/cache_store_adapters.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ module CacheStoreAdapters
5
+ NAMESPACE: String
6
+
7
+ DEFAULT_OPTIONS: Hash[Symbol, untyped]
8
+
9
+ def self._current: () -> ActiveSupport::Cache::Store
10
+
11
+ def self._current=: (ActiveSupport::Cache::Store?) -> void
12
+
13
+ # : () -> ActiveSupport::Cache::Store
14
+ def self.current: () -> ActiveSupport::Cache::Store
15
+
16
+ # : () -> void
17
+ def self.reset!: () -> void
18
+
19
+ # @note
20
+ # - Rails.cache is NOT used directly because JobWorkflow requires namespace isolation from the Rails application's cache store.
21
+ # - JobWorkflow caches are namespaced with "job_workflow" prefix to prevent key collisions with application-level caches.
22
+ # - Using Rails.cache would share namespace configuration with the Rails app, which could lead to conflicts or unintended cache invalidations.
23
+ # - Instead, JobWorkflow creates dedicated ActiveSupport::Cache::Store instances with explicit namespace options.
24
+ #
25
+ # : () -> ActiveSupport::Cache::Store
26
+ private def self.detect_adapter: () -> ActiveSupport::Cache::Store
27
+ end
28
+ end
@@ -0,0 +1,155 @@
1
+ # Generated from lib/job_workflow/context.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ class Context
5
+ # rubocop:disable Metrics/ClassLength
6
+ attr_reader workflow: Workflow
7
+
8
+ attr_reader arguments: Arguments
9
+
10
+ attr_reader output: Output
11
+
12
+ attr_reader job_status: JobStatus
13
+
14
+ # : (Hash[Symbol, untyped]) -> Context
15
+ def self.from_hash: (Hash[Symbol, untyped]) -> Context
16
+
17
+ # : (Hash[String, untyped]) -> Context
18
+ def self.deserialize: (Hash[String, untyped]) -> Context
19
+
20
+ # : (
21
+ # workflow: Workflow,
22
+ # arguments: Arguments,
23
+ # task_context: TaskContext,
24
+ # output: Output,
25
+ # job_status: JobStatus,
26
+ # ?job: DSL?
27
+ # ) -> void
28
+ def initialize: (workflow: Workflow, arguments: Arguments, task_context: TaskContext, output: Output, job_status: JobStatus, ?job: DSL?) -> void
29
+
30
+ # : () -> Hash[String, untyped]
31
+ def serialize: () -> Hash[String, untyped]
32
+
33
+ # : (Hash[Symbol, untyped]) -> Context
34
+ def _update_arguments: (Hash[Symbol, untyped]) -> Context
35
+
36
+ # : (DSL) -> void
37
+ def _job=: (DSL) -> void
38
+
39
+ # : () -> DSL?
40
+ def _job: () -> DSL?
41
+
42
+ # : () -> String
43
+ def job_id: () -> String
44
+
45
+ # : () -> bool
46
+ def sub_job?: () -> bool
47
+
48
+ # : () -> String?
49
+ def concurrency_key: () -> String?
50
+
51
+ # : (Task) -> Enumerator[Context]
52
+ def _with_each_value: (Task) -> Enumerator[Context]
53
+
54
+ # : () { () -> void } -> void
55
+ def _with_task_throttle: () { () -> void } -> void
56
+
57
+ # : (limit: Integer, ?key: String?, ?ttl: Integer) { () -> void } -> void
58
+ def throttle: (limit: Integer, ?key: String?, ?ttl: Integer) { () -> void } -> void
59
+
60
+ # Instruments a custom operation with ActiveSupport::Notifications.
61
+ # This creates a span in OpenTelemetry (if enabled) and logs the event.
62
+ #
63
+ # @example Basic usage
64
+ # ```ruby
65
+ # ctx.instrument("api_call", endpoint: "/users") do
66
+ # HTTP.get("https://api.example.com/users")
67
+ # end
68
+ # ```
69
+ #
70
+ # @example With automatic operation name
71
+ # ```ruby
72
+ # ctx.instrument do
73
+ # # operation name defaults to "custom"
74
+ # expensive_operation()
75
+ # end
76
+ # ```
77
+ #
78
+ # : (?String, **untyped) { () -> untyped } -> untyped
79
+ def instrument: (?String, **untyped) { () -> untyped } -> untyped
80
+
81
+ # : () -> bool
82
+ def dry_run?: () -> bool
83
+
84
+ # : (?Symbol?, ?fallback: untyped) { () -> untyped } -> untyped
85
+ def skip_in_dry_run: (?Symbol?, ?fallback: untyped) { () -> untyped } -> untyped
86
+
87
+ # : () -> untyped
88
+ def each_value: () -> untyped
89
+
90
+ # : () -> TaskOutput?
91
+ def each_task_output: () -> TaskOutput?
92
+
93
+ # : () -> TaskContext
94
+ def _task_context: () -> TaskContext
95
+
96
+ # : (TaskOutput) -> void
97
+ def _add_task_output: (TaskOutput) -> void
98
+
99
+ # : () -> void
100
+ def _load_parent_task_output: () -> void
101
+
102
+ private
103
+
104
+ attr_accessor job: DSL?
105
+
106
+ attr_writer workflow: Workflow
107
+
108
+ attr_writer arguments: Arguments
109
+
110
+ attr_writer output: Output
111
+
112
+ attr_writer job_status: JobStatus
113
+
114
+ attr_accessor task_context: TaskContext
115
+
116
+ attr_accessor enabled_with_each_value: bool
117
+
118
+ attr_accessor throttle_index: Integer
119
+
120
+ attr_accessor skip_in_dry_run_index: Integer
121
+
122
+ # : () -> String
123
+ def parent_job_id: () -> String
124
+
125
+ # : () -> Hash[String, untyped]
126
+ def serialize_for_job: () -> Hash[String, untyped]
127
+
128
+ # : () -> Hash[String, untyped]
129
+ def serialize_for_sub_job: () -> Hash[String, untyped]
130
+
131
+ # : (Task, Enumerator::Yielder) -> void
132
+ def with_task_context: (Task, Enumerator::Yielder) -> void
133
+
134
+ # : (Task) -> void
135
+ def reset_task_context_if_task_changed: (Task) -> void
136
+
137
+ # : (Task) { (untyped, Integer) -> void } -> void
138
+ def with_each_index_and_value: (Task) { (untyped, Integer) -> void } -> void
139
+
140
+ # : () -> void
141
+ def clear_after_each_index_and_value: () -> void
142
+
143
+ # : () { () -> void } -> void
144
+ def with_task_timeout: () { () -> void } -> void
145
+
146
+ # : (Task) { (Integer) -> void } -> void
147
+ def with_retry: (Task) { (Integer) -> void } -> void
148
+
149
+ # : (Task, TaskRetry, Integer, StandardError) -> void
150
+ def wait_next_retry: (Task, TaskRetry, Integer, StandardError) -> void
151
+
152
+ # : (Task) -> bool
153
+ def calculate_dry_run: (Task) -> bool
154
+ end
155
+ end
@@ -0,0 +1,16 @@
1
+ # Generated from lib/job_workflow/dry_run_config.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ class DryRunConfig
5
+ attr_reader evaluator: ^(Context) -> bool
6
+
7
+ # : (bool | ^(Context) -> bool | nil) -> DryRunConfig
8
+ def self.from_primitive_value: (bool | ^(Context) -> bool | nil) -> DryRunConfig
9
+
10
+ # : (?evaluator: ^(Context) -> bool) -> void
11
+ def initialize: (?evaluator: ^(Context) -> bool) -> void
12
+
13
+ # : (Context) -> bool
14
+ def evaluate: (Context) -> bool
15
+ end
16
+ end
@@ -0,0 +1,117 @@
1
+ # Generated from lib/job_workflow/dsl.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ module DSL
5
+ extend ActiveSupport::Concern
6
+
7
+ include ActiveJob::Continuable
8
+
9
+ extend ClassMethods
10
+
11
+ def self._included_classes: () -> Set[singleton(DSL)]
12
+
13
+ def class: () -> ClassMethods
14
+
15
+ def job_id: () -> String
16
+
17
+ def queue_name: () -> String
18
+
19
+ def set: (Hash[Symbol, untyped]) -> self
20
+
21
+ def step: (Symbol, ?start: ActiveJob::Continuation::_Succ, ?isolated: bool) -> void
22
+ | (Symbol, ?start: ActiveJob::Continuation::_Succ, ?isolated: bool) { (ActiveJob::Continuation::Step) -> void } -> void
23
+
24
+ # : (Hash[untyped, untyped]) -> void
25
+ def perform: (Hash[untyped, untyped]) -> void
26
+
27
+ # : () -> Output
28
+ def output: () -> Output
29
+
30
+ # : (Context) -> void
31
+ def _context=: (Context) -> void
32
+
33
+ # : () -> Context?
34
+ def _context: () -> Context?
35
+
36
+ # : () -> Hash[String, untyped]
37
+ def serialize: () -> Hash[String, untyped]
38
+
39
+ # : (Hash[String, untyped]) -> void
40
+ def deserialize: (Hash[String, untyped]) -> void
41
+
42
+ module ClassMethods
43
+ def class_attribute: (Symbol, default: untyped) -> void
44
+
45
+ def _workflow: () -> Workflow
46
+
47
+ def new: (Hash[untyped, untyped]) -> DSL
48
+
49
+ def name: () -> String
50
+
51
+ def enqueue: (Hash[untyped, untyped]) -> void
52
+
53
+ def queue_name: () -> String
54
+
55
+ def queue_as: () -> String
56
+
57
+ def limits_concurrency: (to: Integer, key: ^(untyped) -> untyped, ?duration: ActiveSupport::Duration?, ?group: String?, ?on_conflict: Symbol?) -> void
58
+
59
+ # : (Context) -> DSL
60
+ def from_context: (Context) -> DSL
61
+
62
+ # : (Symbol argument_name, String type, ?default: untyped) -> void
63
+ def argument: (Symbol argument_name, String type, ?default: untyped) -> void
64
+
65
+ # : (Symbol) { () -> void } -> void
66
+ def namespace: (Symbol) { () -> void } -> void
67
+
68
+ # rubocop:disable Metrics/ParameterLists
69
+ #
70
+ # : (
71
+ # Symbol task_name,
72
+ # ?each: ^(Context) -> untyped,
73
+ # ?enqueue: true | false | ^(Context) -> bool | Hash[Symbol, untyped],
74
+ # ?retry: Integer | Hash[Symbol, untyped],
75
+ # ?output: Hash[Symbol, String],
76
+ # ?depends_on: Array[Symbol],
77
+ # ?condition: ^(Context) -> bool,
78
+ # ?throttle: Integer | Hash[Symbol, untyped],
79
+ # ?timeout: Numeric?,
80
+ # ?dependency_wait: Hash[Symbol, untyped],
81
+ # ?dry_run: bool | ^(Context) -> bool
82
+ # ) { (untyped) -> void } -> void
83
+ def task: (Symbol task_name, ?each: ^(Context) -> untyped, ?enqueue: true | false | ^(Context) -> bool | Hash[Symbol, untyped], ?retry: Integer | Hash[Symbol, untyped], ?output: Hash[Symbol, String], ?depends_on: Array[Symbol], ?condition: ^(Context) -> bool, ?throttle: Integer | Hash[Symbol, untyped], ?timeout: Numeric?, ?dependency_wait: Hash[Symbol, untyped], ?dry_run: bool | ^(Context) -> bool) { (untyped) -> void } -> void
84
+
85
+ # : (*Symbol) { (Context) -> void } -> void
86
+ def before: (*Symbol) { (Context) -> void } -> void
87
+
88
+ # : (*Symbol) { (Context) -> void } -> void
89
+ def after: (*Symbol) { (Context) -> void } -> void
90
+
91
+ # : (*Symbol) { (Context, TaskCallable) -> void } -> void
92
+ def around: (*Symbol) { (Context, TaskCallable) -> void } -> void
93
+
94
+ # : (*Symbol) { (Context, StandardError, Task) -> void } -> void
95
+ def on_error: (*Symbol) { (Context, StandardError, Task) -> void } -> void
96
+
97
+ # : (?bool) ?{ (Context) -> bool } -> void
98
+ def dry_run: (?bool) ?{ (Context) -> bool } -> void
99
+
100
+ # rubocop:disable Metrics/ParameterLists
101
+ # : (
102
+ # String expression,
103
+ # ?key: (String | Symbol)?,
104
+ # ?queue: String?,
105
+ # ?priority: Integer?,
106
+ # ?args: Hash[Symbol, untyped],
107
+ # ?description: String?
108
+ # ) -> void
109
+ def schedule: (String expression, ?key: (String | Symbol)?, ?queue: String?, ?priority: Integer?, ?args: Hash[Symbol, untyped], ?description: String?) -> void
110
+
111
+ private
112
+
113
+ # : () -> void
114
+ def validate_namespace!: () -> void
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,18 @@
1
+ # Generated from lib/job_workflow/error_hook.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ class ErrorHook
5
+ attr_reader task_names: Set[Symbol]
6
+
7
+ attr_reader block: ^(Context, StandardError, Task) -> void
8
+
9
+ # : (task_names: Array[Symbol], block: ^(Context, StandardError, Task) -> void) -> void
10
+ def initialize: (task_names: Array[Symbol], block: ^(Context, StandardError, Task) -> void) -> void
11
+
12
+ # : (Symbol) -> bool
13
+ def applies_to?: (Symbol) -> bool
14
+
15
+ # : () -> bool
16
+ def global?: () -> bool
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # Generated from lib/job_workflow/hook.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ class Hook
5
+ attr_reader task_names: Set[Symbol]
6
+
7
+ attr_reader block: ^(Context, ?TaskCallable) -> void
8
+
9
+ # : (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
10
+ def initialize: (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
11
+
12
+ # : (Symbol) -> bool
13
+ def applies_to?: (Symbol) -> bool
14
+
15
+ # : () -> bool
16
+ def global?: () -> bool
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ # Generated from lib/job_workflow/hook_registry.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ class HookRegistry
5
+ # : () -> void
6
+ def initialize: () -> void
7
+
8
+ # : (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
9
+ def add_before_hook: (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
10
+
11
+ # : (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
12
+ def add_after_hook: (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
13
+
14
+ # : (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
15
+ def add_around_hook: (task_names: Array[Symbol], block: ^(Context, ?TaskCallable) -> void) -> void
16
+
17
+ # : (task_names: Array[Symbol], block: ^(Context, StandardError, Task) -> void) -> void
18
+ def add_error_hook: (task_names: Array[Symbol], block: ^(Context, StandardError, Task) -> void) -> void
19
+
20
+ # : (Symbol) -> Array[Hook]
21
+ def before_hooks_for: (Symbol) -> Array[Hook]
22
+
23
+ # : (Symbol) -> Array[Hook]
24
+ def after_hooks_for: (Symbol) -> Array[Hook]
25
+
26
+ # : (Symbol) -> Array[Hook]
27
+ def around_hooks_for: (Symbol) -> Array[Hook]
28
+
29
+ # : (Symbol) -> Array[ErrorHook]
30
+ def error_hooks_for: (Symbol) -> Array[ErrorHook]
31
+
32
+ private
33
+
34
+ attr_accessor before_hooks: Array[Hook]
35
+
36
+ attr_accessor after_hooks: Array[Hook]
37
+
38
+ attr_accessor around_hooks: Array[Hook]
39
+
40
+ attr_accessor error_hooks: Array[ErrorHook]
41
+
42
+ # : (Array[Hook], Symbol) -> Array[Hook]
43
+ # : (Array[ErrorHook], Symbol) -> Array[ErrorHook]
44
+ def hooks_for: (Array[Hook], Symbol) -> Array[Hook]
45
+ | (Array[ErrorHook], Symbol) -> Array[ErrorHook]
46
+ end
47
+ end
@@ -0,0 +1,102 @@
1
+ # Generated from lib/job_workflow/instrumentation/log_subscriber.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ module Instrumentation
5
+ # LogSubscriber handles JobWorkflow instrumentation events and produces structured JSON logs.
6
+ # It subscribes to ActiveSupport::Notifications events and formats them for logging.
7
+ #
8
+ # @example Enable log subscriber
9
+ # ```ruby
10
+ # JobWorkflow::Instrumentation::LogSubscriber.attach_to(:job_workflow)
11
+ # ```
12
+ class LogSubscriber < ActiveSupport::LogSubscriber
13
+ # : () -> void
14
+ def self.attach!: () -> void
15
+
16
+ type log_level = :debug | :info | :warn | :error
17
+
18
+ # : (ActiveSupport::Notifications::Event) -> void
19
+ def workflow: (ActiveSupport::Notifications::Event) -> void
20
+
21
+ # : (ActiveSupport::Notifications::Event) -> void
22
+ def workflow_start: (ActiveSupport::Notifications::Event) -> void
23
+
24
+ # : (ActiveSupport::Notifications::Event) -> void
25
+ def workflow_complete: (ActiveSupport::Notifications::Event) -> void
26
+
27
+ # : (ActiveSupport::Notifications::Event) -> void
28
+ def task: (ActiveSupport::Notifications::Event) -> void
29
+
30
+ # : (ActiveSupport::Notifications::Event) -> void
31
+ def task_start: (ActiveSupport::Notifications::Event) -> void
32
+
33
+ # : (ActiveSupport::Notifications::Event) -> void
34
+ def task_complete: (ActiveSupport::Notifications::Event) -> void
35
+
36
+ # : (ActiveSupport::Notifications::Event) -> void
37
+ def task_error: (ActiveSupport::Notifications::Event) -> void
38
+
39
+ # : (ActiveSupport::Notifications::Event) -> void
40
+ def task_skip: (ActiveSupport::Notifications::Event) -> void
41
+
42
+ # : (ActiveSupport::Notifications::Event) -> void
43
+ def task_enqueue: (ActiveSupport::Notifications::Event) -> void
44
+
45
+ # : (ActiveSupport::Notifications::Event) -> void
46
+ def task_retry: (ActiveSupport::Notifications::Event) -> void
47
+
48
+ # : (ActiveSupport::Notifications::Event) -> void
49
+ def throttle_acquire: (ActiveSupport::Notifications::Event) -> void
50
+
51
+ # : (ActiveSupport::Notifications::Event) -> void
52
+ def throttle_acquire_start: (ActiveSupport::Notifications::Event) -> void
53
+
54
+ # : (ActiveSupport::Notifications::Event) -> void
55
+ def throttle_acquire_complete: (ActiveSupport::Notifications::Event) -> void
56
+
57
+ # : (ActiveSupport::Notifications::Event) -> void
58
+ def throttle_release: (ActiveSupport::Notifications::Event) -> void
59
+
60
+ # : (ActiveSupport::Notifications::Event) -> void
61
+ def dependent_wait: (ActiveSupport::Notifications::Event) -> void
62
+
63
+ # : (ActiveSupport::Notifications::Event) -> void
64
+ def dependent_wait_start: (ActiveSupport::Notifications::Event) -> void
65
+
66
+ # : (ActiveSupport::Notifications::Event) -> void
67
+ def dependent_wait_complete: (ActiveSupport::Notifications::Event) -> void
68
+
69
+ # : (ActiveSupport::Notifications::Event) -> void
70
+ def queue_pause: (ActiveSupport::Notifications::Event) -> void
71
+
72
+ # : (ActiveSupport::Notifications::Event) -> void
73
+ def queue_resume: (ActiveSupport::Notifications::Event) -> void
74
+
75
+ # : (ActiveSupport::Notifications::Event) -> void
76
+ def dry_run: (ActiveSupport::Notifications::Event) -> void
77
+
78
+ # : (ActiveSupport::Notifications::Event) -> void
79
+ def dry_run_skip: (ActiveSupport::Notifications::Event) -> void
80
+
81
+ # : (ActiveSupport::Notifications::Event) -> void
82
+ def dry_run_execute: (ActiveSupport::Notifications::Event) -> void
83
+
84
+ private
85
+
86
+ # : (ActiveSupport::Notifications::Event, log_level) -> void
87
+ def log_event: (ActiveSupport::Notifications::Event, log_level) -> void
88
+
89
+ # : (ActiveSupport::Notifications::Event) -> Hash[Symbol, untyped]
90
+ def build_log_payload: (ActiveSupport::Notifications::Event) -> Hash[Symbol, untyped]
91
+
92
+ # : (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
93
+ def extract_loggable_attributes: (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
94
+
95
+ # : (Hash[Symbol, untyped], Hash[Symbol, untyped]) -> void
96
+ def add_error_attributes: (Hash[Symbol, untyped], Hash[Symbol, untyped]) -> void
97
+
98
+ # : (log_level, Hash[Symbol, untyped]) -> void
99
+ def send_log: (log_level, Hash[Symbol, untyped]) -> void
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,113 @@
1
+ # Generated from lib/job_workflow/instrumentation/opentelemetry_subscriber.rb with RBS::Inline
2
+
3
+ module JobWorkflow
4
+ module Instrumentation
5
+ # OpenTelemetrySubscriber provides OpenTelemetry tracing integration for JobWorkflow events.
6
+ # It subscribes to ActiveSupport::Notifications and creates OpenTelemetry spans.
7
+ #
8
+ # @example Enable OpenTelemetry integration
9
+ # ```ruby
10
+ # # Ensure OpenTelemetry is configured first
11
+ # OpenTelemetry::SDK.configure do |c|
12
+ # c.service_name = "my-app"
13
+ # end
14
+ #
15
+ # # Then subscribe JobWorkflow events
16
+ # JobWorkflow::Instrumentation::OpenTelemetrySubscriber.subscribe!
17
+ # ```
18
+ #
19
+ # @note This subscriber requires the opentelemetry-api gem to be installed.
20
+ # If not available, subscription will be silently skipped.
21
+ class OpenTelemetrySubscriber
22
+ # rubocop:disable Metrics/ClassLength
23
+ module Attributes
24
+ JOB_NAME: String
25
+
26
+ JOB_ID: String
27
+
28
+ TASK_NAME: String
29
+
30
+ TASK_EACH_INDEX: String
31
+
32
+ TASK_RETRY_COUNT: String
33
+
34
+ WORKFLOW_NAME: String
35
+
36
+ ERROR_CLASS: String
37
+
38
+ ERROR_MESSAGE: String
39
+
40
+ CONCURRENCY_KEY: String
41
+
42
+ CONCURRENCY_LIMIT: String
43
+ end
44
+
45
+ SUBSCRIBED_EVENTS: untyped
46
+
47
+ def self.subscriptions: () -> Array[untyped]
48
+
49
+ def self.subscriptions=: (Array[untyped]) -> void
50
+
51
+ # : () -> Array[untyped]?
52
+ def self.subscribe!: () -> Array[untyped]?
53
+
54
+ # : () -> void
55
+ def self.unsubscribe!: () -> void
56
+
57
+ # : () -> void
58
+ def self.reset!: () -> void
59
+
60
+ # : () -> bool
61
+ def self.opentelemetry_available?: () -> bool
62
+
63
+ # : (String, String, Hash[Symbol, untyped]) -> void
64
+ def start: (String, String, Hash[Symbol, untyped]) -> void
65
+
66
+ # : (String, String, Hash[Symbol, untyped]) -> void
67
+ def finish: (String, String, Hash[Symbol, untyped]) -> void
68
+
69
+ private
70
+
71
+ # : (Hash[Symbol, untyped]) -> Array[untyped?]
72
+ def extract_otel_info: (Hash[Symbol, untyped]) -> Array[untyped?]
73
+
74
+ def start_span: (untyped name, untyped payload) -> untyped
75
+
76
+ # : (untyped) -> untyped
77
+ def attach_span_context: (untyped) -> untyped
78
+
79
+ # : (Hash[Symbol, untyped], untyped, untyped) -> void
80
+ def store_span_info: (Hash[Symbol, untyped], untyped, untyped) -> void
81
+
82
+ # : (Hash[Symbol, untyped], untyped) -> void
83
+ def handle_exception: (Hash[Symbol, untyped], untyped) -> void
84
+
85
+ # : (untyped, untyped) -> void
86
+ def finish_span: (untyped, untyped) -> void
87
+
88
+ # : (untyped) -> void
89
+ def finish_span_safe: (untyped) -> void
90
+
91
+ # : (untyped) -> void
92
+ def detach_context_safe: (untyped) -> void
93
+
94
+ # : (String, Hash[Symbol, untyped]) -> String
95
+ def build_span_name: (String, Hash[Symbol, untyped]) -> String
96
+
97
+ # : (Hash[Symbol, untyped]) -> Hash[String, untyped]
98
+ def build_attributes: (Hash[Symbol, untyped]) -> Hash[String, untyped]
99
+
100
+ # : (Hash[String, untyped], Hash[Symbol, untyped]) -> void
101
+ def add_error_attributes: (Hash[String, untyped], Hash[Symbol, untyped]) -> void
102
+
103
+ # : (String) -> Symbol
104
+ def determine_span_kind: (String) -> Symbol
105
+
106
+ # : () -> untyped
107
+ def tracer: () -> untyped
108
+
109
+ # : (StandardError) -> void
110
+ def handle_error: (StandardError) -> void
111
+ end
112
+ end
113
+ end