taski 0.8.3 → 0.9.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 +52 -0
- data/README.md +108 -50
- data/docs/GUIDE.md +79 -55
- data/examples/README.md +10 -29
- data/examples/clean_demo.rb +25 -65
- data/examples/large_tree_demo.rb +356 -0
- data/examples/message_demo.rb +0 -1
- data/examples/progress_demo.rb +13 -24
- data/examples/reexecution_demo.rb +8 -44
- data/lib/taski/execution/execution_facade.rb +150 -0
- data/lib/taski/execution/executor.rb +167 -359
- data/lib/taski/execution/fiber_protocol.rb +27 -0
- data/lib/taski/execution/registry.rb +15 -19
- data/lib/taski/execution/scheduler.rb +161 -140
- data/lib/taski/execution/task_observer.rb +41 -0
- data/lib/taski/execution/task_output_router.rb +41 -58
- data/lib/taski/execution/task_wrapper.rb +123 -219
- data/lib/taski/execution/worker_pool.rb +279 -64
- data/lib/taski/logging.rb +105 -0
- data/lib/taski/progress/layout/base.rb +600 -0
- data/lib/taski/progress/layout/filters.rb +126 -0
- data/lib/taski/progress/layout/log.rb +27 -0
- data/lib/taski/progress/layout/simple.rb +166 -0
- data/lib/taski/progress/layout/tags.rb +76 -0
- data/lib/taski/progress/layout/theme_drop.rb +84 -0
- data/lib/taski/progress/layout/tree.rb +300 -0
- data/lib/taski/progress/theme/base.rb +224 -0
- data/lib/taski/progress/theme/compact.rb +58 -0
- data/lib/taski/progress/theme/default.rb +25 -0
- data/lib/taski/progress/theme/detail.rb +48 -0
- data/lib/taski/progress/theme/plain.rb +40 -0
- data/lib/taski/static_analysis/analyzer.rb +5 -17
- data/lib/taski/static_analysis/dependency_graph.rb +19 -1
- data/lib/taski/static_analysis/start_dep_analyzer.rb +400 -0
- data/lib/taski/static_analysis/visitor.rb +1 -39
- data/lib/taski/task.rb +49 -58
- data/lib/taski/task_proxy.rb +59 -0
- data/lib/taski/test_helper/errors.rb +1 -1
- data/lib/taski/test_helper.rb +22 -36
- data/lib/taski/version.rb +1 -1
- data/lib/taski.rb +62 -61
- data/sig/taski.rbs +194 -203
- metadata +34 -8
- data/examples/section_demo.rb +0 -195
- data/lib/taski/execution/base_progress_display.rb +0 -393
- data/lib/taski/execution/execution_context.rb +0 -390
- data/lib/taski/execution/plain_progress_display.rb +0 -76
- data/lib/taski/execution/simple_progress_display.rb +0 -247
- data/lib/taski/execution/tree_progress_display.rb +0 -643
- data/lib/taski/section.rb +0 -74
data/sig/taski.rbs
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
module Taski
|
|
2
2
|
VERSION: String
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
self.@progress_display:
|
|
4
|
+
NOT_CONFIGURED: Object
|
|
5
|
+
self.@progress_display: Progress::Layout::Base | Object | nil
|
|
6
6
|
self.@args: Args?
|
|
7
7
|
self.@args_monitor: Monitor
|
|
8
8
|
|
|
9
9
|
# Type alias for Task class (singleton type with class methods)
|
|
10
10
|
# This represents a Class that inherits from Taski::Task
|
|
11
11
|
type task_class = singleton(Task)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def self.global_registry: () -> Execution::Registry
|
|
15
|
-
def self.reset_global_registry!: () -> void
|
|
16
|
-
def self.progress_display: () -> Execution::TreeProgressDisplay?
|
|
17
|
-
def self.progress_disabled?: () -> bool
|
|
12
|
+
def self.progress_display: () -> (Progress::Layout::Base | untyped)?
|
|
13
|
+
def self.progress_display=: (untyped display) -> void
|
|
18
14
|
def self.reset_progress_display!: () -> void
|
|
19
15
|
def self.args: () -> Args?
|
|
20
|
-
def self.start_args: (options: Hash[Symbol, untyped]
|
|
16
|
+
def self.start_args: (options: Hash[Symbol, untyped]) -> void
|
|
21
17
|
def self.reset_args!: () -> void
|
|
22
18
|
def self.args_worker_count: () -> Integer?
|
|
23
19
|
|
|
@@ -37,11 +33,13 @@ module Taski
|
|
|
37
33
|
class TaskFailure
|
|
38
34
|
@task_class: Class
|
|
39
35
|
@error: Exception
|
|
36
|
+
@output_lines: Array[String]
|
|
40
37
|
|
|
41
38
|
attr_reader task_class: Class
|
|
42
39
|
attr_reader error: Exception
|
|
40
|
+
attr_reader output_lines: Array[String]
|
|
43
41
|
|
|
44
|
-
def initialize: (task_class: Class, error: Exception) -> void
|
|
42
|
+
def initialize: (task_class: Class, error: Exception, ?output_lines: Array[String]) -> void
|
|
45
43
|
end
|
|
46
44
|
|
|
47
45
|
# Mixin for exception classes to enable transparent rescue matching with AggregateError
|
|
@@ -80,15 +78,8 @@ module Taski
|
|
|
80
78
|
# Args class for execution arguments management
|
|
81
79
|
class Args
|
|
82
80
|
@options: Hash[Symbol | String, untyped]
|
|
83
|
-
@root_task: Class
|
|
84
|
-
@started_at: Time
|
|
85
|
-
@working_directory: String
|
|
86
|
-
|
|
87
|
-
attr_reader started_at: Time
|
|
88
|
-
attr_reader working_directory: String
|
|
89
|
-
attr_reader root_task: Class
|
|
90
81
|
|
|
91
|
-
def initialize: (options: Hash[Symbol | String, untyped]
|
|
82
|
+
def initialize: (options: Hash[Symbol | String, untyped]) -> void
|
|
92
83
|
def []: (Symbol | String key) -> untyped
|
|
93
84
|
def fetch: (Symbol | String key, ?untyped default) ?{ () -> untyped } -> untyped
|
|
94
85
|
def key?: (Symbol | String key) -> bool
|
|
@@ -109,7 +100,7 @@ module Taski
|
|
|
109
100
|
def self.clear_dependency_cache: () -> void
|
|
110
101
|
def self.run: (?args: Hash[Symbol, untyped], ?workers: Integer?) -> untyped
|
|
111
102
|
def self.clean: (?args: Hash[Symbol, untyped], ?workers: Integer?) -> void
|
|
112
|
-
def self.run_and_clean: (?args: Hash[Symbol, untyped], ?workers: Integer?) -> untyped
|
|
103
|
+
def self.run_and_clean: (?args: Hash[Symbol, untyped], ?workers: Integer?, ?clean_on_failure: bool) ?{ () -> void } -> untyped
|
|
113
104
|
def self.registry: () -> Execution::Registry
|
|
114
105
|
def self.reset!: () -> void
|
|
115
106
|
def self.tree: () -> String
|
|
@@ -117,6 +108,7 @@ module Taski
|
|
|
117
108
|
# Instance methods
|
|
118
109
|
def run: () -> void
|
|
119
110
|
def clean: () -> void
|
|
111
|
+
def group: (String name) { () -> untyped } -> untyped
|
|
120
112
|
def system: (*untyped args, **untyped opts) -> bool?
|
|
121
113
|
def reset!: () -> void
|
|
122
114
|
|
|
@@ -130,36 +122,18 @@ module Taski
|
|
|
130
122
|
def self.validate_workers!: (untyped workers) -> void
|
|
131
123
|
end
|
|
132
124
|
|
|
133
|
-
# Section class for abstraction layers (inherits from Task)
|
|
134
|
-
class Section < Task
|
|
135
|
-
def self.interfaces: (*Symbol interface_methods) -> void
|
|
136
|
-
|
|
137
|
-
def run: () -> void
|
|
138
|
-
def impl: () -> task_class
|
|
139
|
-
|
|
140
|
-
private
|
|
141
|
-
|
|
142
|
-
def apply_interface_to_implementation: (task_class implementation_class) -> void
|
|
143
|
-
end
|
|
144
|
-
|
|
145
125
|
# Execution module
|
|
146
126
|
module Execution
|
|
147
|
-
#
|
|
148
|
-
class
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def
|
|
157
|
-
| (start_time: Time, end_time: Time?) -> TaskTiming
|
|
158
|
-
|
|
159
|
-
def self.start_now: () -> TaskTiming
|
|
160
|
-
def duration_ms: () -> (Integer | Float)?
|
|
161
|
-
def with_end_now: () -> TaskTiming
|
|
162
|
-
def with: (?start_time: Time, ?end_time: Time?) -> TaskTiming
|
|
127
|
+
# Base class for observers of the execution lifecycle
|
|
128
|
+
class TaskObserver
|
|
129
|
+
attr_accessor context: ExecutionFacade?
|
|
130
|
+
|
|
131
|
+
def on_ready: () -> void
|
|
132
|
+
def on_start: () -> void
|
|
133
|
+
def on_stop: () -> void
|
|
134
|
+
def on_task_updated: (Class task_class, previous_state: Symbol?, current_state: Symbol, phase: Symbol, timestamp: Time) -> void
|
|
135
|
+
def on_group_started: (Class task_class, String group_name, phase: Symbol, timestamp: Time) -> void
|
|
136
|
+
def on_group_completed: (Class task_class, String group_name, phase: Symbol, timestamp: Time) -> void
|
|
163
137
|
end
|
|
164
138
|
|
|
165
139
|
# Registry class for task instance management
|
|
@@ -171,57 +145,55 @@ module Taski
|
|
|
171
145
|
|
|
172
146
|
def initialize: () -> void
|
|
173
147
|
def get_or_create: (Class task_class) { () -> TaskWrapper } -> TaskWrapper
|
|
174
|
-
def
|
|
148
|
+
def create_wrapper: (Class task_class, execution_facade: ExecutionFacade) -> TaskWrapper
|
|
175
149
|
def register: (Class task_class, TaskWrapper wrapper) -> void
|
|
176
150
|
def register_thread: (Thread thread) -> void
|
|
177
151
|
def wait_all: () -> void
|
|
178
152
|
def reset!: () -> void
|
|
179
153
|
def request_abort!: () -> void
|
|
180
154
|
def abort_requested?: () -> bool
|
|
181
|
-
def
|
|
155
|
+
def registered?: (Class task_class) -> bool
|
|
182
156
|
def failed_wrappers: () -> Array[TaskWrapper]
|
|
183
157
|
def failed_clean_wrappers: () -> Array[TaskWrapper]
|
|
184
158
|
end
|
|
185
159
|
|
|
186
|
-
#
|
|
187
|
-
class
|
|
160
|
+
# ExecutionFacade is the central hub for execution events with both Push and Pull APIs
|
|
161
|
+
class ExecutionFacade
|
|
188
162
|
THREAD_LOCAL_KEY: Symbol
|
|
189
163
|
|
|
164
|
+
attr_reader root_task_class: Class?
|
|
165
|
+
attr_reader dependency_graph: StaticAnalysis::DependencyGraph?
|
|
166
|
+
|
|
167
|
+
@root_task_class: Class?
|
|
168
|
+
@dependency_graph: StaticAnalysis::DependencyGraph?
|
|
190
169
|
@monitor: Monitor
|
|
191
170
|
@observers: Array[untyped]
|
|
192
|
-
@execution_trigger: (^(Class, Registry) -> void)?
|
|
193
|
-
@clean_trigger: (^(Class, Registry) -> void)?
|
|
194
171
|
@output_capture: TaskOutputRouter?
|
|
195
172
|
@original_stdout: IO?
|
|
196
|
-
@
|
|
173
|
+
@original_stderr: IO?
|
|
197
174
|
|
|
198
|
-
def self.
|
|
199
|
-
def self.current
|
|
175
|
+
def self.build_default: (root_task_class: Class) -> ExecutionFacade
|
|
176
|
+
def self.current: () -> ExecutionFacade?
|
|
177
|
+
def self.current=: (ExecutionFacade? context) -> void
|
|
200
178
|
|
|
201
|
-
def initialize: () -> void
|
|
179
|
+
def initialize: (root_task_class: Class) -> void
|
|
202
180
|
def output_capture_active?: () -> bool
|
|
181
|
+
def original_stdout: () -> IO?
|
|
182
|
+
def original_stderr: () -> IO?
|
|
203
183
|
def setup_output_capture: (IO output_io) -> void
|
|
204
184
|
def teardown_output_capture: () -> void
|
|
205
185
|
def output_capture: () -> TaskOutputRouter?
|
|
206
|
-
def execution_trigger=: ((^(Class, Registry) -> void)? trigger) -> void
|
|
207
|
-
def clean_trigger=: ((^(Class, Registry) -> void)? trigger) -> void
|
|
208
186
|
def trigger_execution: (Class task_class, registry: Registry) -> void
|
|
209
|
-
def trigger_clean: (Class task_class, registry: Registry) ->
|
|
210
|
-
def register_runtime_dependency: (Class from_class, Class to_class) -> void
|
|
211
|
-
def runtime_dependencies: () -> Hash[Class, Set[Class]]
|
|
187
|
+
def trigger_clean: (Class task_class, registry: Registry) -> void
|
|
212
188
|
def add_observer: (untyped observer) -> void
|
|
213
189
|
def remove_observer: (untyped observer) -> void
|
|
214
190
|
def observers: () -> Array[untyped]
|
|
215
|
-
def
|
|
216
|
-
def notify_task_started: (Class task_class) -> void
|
|
217
|
-
def notify_task_completed: (Class task_class, ?duration: Float?, ?error: Exception?) -> void
|
|
218
|
-
def notify_section_impl_selected: (Class section_class, Class impl_class) -> void
|
|
219
|
-
def notify_set_root_task: (Class task_class) -> void
|
|
220
|
-
def notify_set_output_capture: (TaskOutputRouter output_capture) -> void
|
|
191
|
+
def notify_ready: () -> void
|
|
221
192
|
def notify_start: () -> void
|
|
222
193
|
def notify_stop: () -> void
|
|
223
|
-
def
|
|
224
|
-
def
|
|
194
|
+
def notify_task_updated: (Class task_class, previous_state: Symbol?, current_state: Symbol, phase: Symbol, timestamp: Time) -> void
|
|
195
|
+
def notify_group_started: (Class task_class, String group_name, phase: Symbol, timestamp: Time) -> void
|
|
196
|
+
def notify_group_completed: (Class task_class, String group_name, phase: Symbol, timestamp: Time) -> void
|
|
225
197
|
|
|
226
198
|
private
|
|
227
199
|
|
|
@@ -230,41 +202,49 @@ module Taski
|
|
|
230
202
|
|
|
231
203
|
# TaskOutputRouter for routing task output
|
|
232
204
|
class TaskOutputRouter
|
|
233
|
-
def initialize: (IO original_io) -> void
|
|
205
|
+
def initialize: (IO original_io, ?ExecutionFacade? execution_facade) -> void
|
|
234
206
|
def current_write_io: () -> IO?
|
|
235
207
|
def start_capture: (Class task_class) -> void
|
|
236
208
|
def stop_capture: () -> void
|
|
209
|
+
def read: (Class task_class, ?limit: Integer?) -> Array[String]
|
|
237
210
|
end
|
|
238
211
|
|
|
239
212
|
# Scheduler manages task dependency state and determines execution order
|
|
240
213
|
class Scheduler
|
|
241
214
|
STATE_PENDING: Symbol
|
|
242
|
-
|
|
215
|
+
STATE_RUNNING: Symbol
|
|
243
216
|
STATE_COMPLETED: Symbol
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
CLEAN_STATE_COMPLETED: Symbol
|
|
217
|
+
STATE_FAILED: Symbol
|
|
218
|
+
STATE_SKIPPED: Symbol
|
|
247
219
|
|
|
248
|
-
@dependencies: Hash[Class,
|
|
220
|
+
@dependencies: Hash[Class, Array[Class]]
|
|
249
221
|
@task_states: Hash[Class, Symbol]
|
|
250
|
-
@
|
|
222
|
+
@finished_tasks: Set[Class]
|
|
223
|
+
@run_reverse_deps: Hash[Class, Set[Class]]
|
|
251
224
|
@reverse_dependencies: Hash[Class, Set[Class]]
|
|
252
225
|
@clean_task_states: Hash[Class, Symbol]
|
|
253
|
-
@
|
|
226
|
+
@clean_finished_tasks: Set[Class]
|
|
254
227
|
|
|
255
228
|
def initialize: () -> void
|
|
256
|
-
def
|
|
229
|
+
def load_graph: (StaticAnalysis::DependencyGraph dependency_graph, Class root_task_class) -> void
|
|
257
230
|
def next_ready_tasks: () -> Array[Class]
|
|
258
|
-
def
|
|
231
|
+
def mark_running: (Class task_class) -> void
|
|
259
232
|
def mark_completed: (Class task_class) -> void
|
|
260
|
-
def
|
|
233
|
+
def mark_failed: (Class task_class) -> void
|
|
234
|
+
def pending?: (Class task_class) -> bool
|
|
235
|
+
def finished?: (Class task_class) -> bool
|
|
261
236
|
def running_tasks?: () -> bool
|
|
262
|
-
def
|
|
263
|
-
def
|
|
237
|
+
def task_count: () -> Integer
|
|
238
|
+
def never_started_task_classes: () -> Array[Class]
|
|
239
|
+
def mark_skipped: (Class task_class) -> bool
|
|
240
|
+
def skipped_count: () -> Integer
|
|
241
|
+
def pending_dependents_of: (Class task_class) -> Array[Class]
|
|
242
|
+
def build_reverse_dependency_graph: () -> void
|
|
264
243
|
def next_ready_clean_tasks: () -> Array[Class]
|
|
265
|
-
def
|
|
244
|
+
def mark_clean_running: (Class task_class) -> void
|
|
266
245
|
def mark_clean_completed: (Class task_class) -> void
|
|
267
|
-
def
|
|
246
|
+
def mark_clean_failed: (Class task_class) -> void
|
|
247
|
+
def clean_finished?: (Class task_class) -> bool
|
|
268
248
|
def running_clean_tasks?: () -> bool
|
|
269
249
|
|
|
270
250
|
private
|
|
@@ -273,72 +253,94 @@ module Taski
|
|
|
273
253
|
def ready_to_clean?: (Class task_class) -> bool
|
|
274
254
|
end
|
|
275
255
|
|
|
276
|
-
|
|
256
|
+
def self.default_worker_count: () -> Integer
|
|
257
|
+
|
|
258
|
+
# WorkerPool manages N threads, each with its own command Queue
|
|
259
|
+
# Tasks are executed within Fibers on worker threads
|
|
277
260
|
class WorkerPool
|
|
278
|
-
attr_reader
|
|
261
|
+
attr_reader worker_count: Integer
|
|
279
262
|
|
|
280
|
-
@worker_count: Integer
|
|
281
263
|
@registry: Registry
|
|
282
|
-
@
|
|
283
|
-
@
|
|
284
|
-
@
|
|
264
|
+
@execution_facade: ExecutionFacade
|
|
265
|
+
@worker_count: Integer
|
|
266
|
+
@completion_queue: Thread::Queue
|
|
267
|
+
@threads: Array[Thread]
|
|
268
|
+
@thread_queues: Array[Thread::Queue]
|
|
269
|
+
@next_thread_index: Integer
|
|
270
|
+
@fiber_contexts_mutex: Mutex
|
|
271
|
+
@fiber_contexts: Hash[Integer, Array[untyped]]
|
|
272
|
+
@task_start_times: Hash[Class, Time]
|
|
285
273
|
|
|
286
|
-
def initialize: (registry: Registry, ?worker_count: Integer?)
|
|
274
|
+
def initialize: (registry: Registry, execution_facade: ExecutionFacade, completion_queue: Thread::Queue, ?worker_count: Integer?) -> void
|
|
287
275
|
def start: () -> void
|
|
288
276
|
def enqueue: (Class task_class, TaskWrapper wrapper) -> void
|
|
277
|
+
def enqueue_clean: (Class task_class, TaskWrapper wrapper) -> void
|
|
289
278
|
def shutdown: () -> void
|
|
290
|
-
def enqueue_shutdown_signals: () -> void
|
|
291
279
|
|
|
292
280
|
private
|
|
293
281
|
|
|
294
|
-
def
|
|
295
|
-
def
|
|
296
|
-
def
|
|
282
|
+
def worker_loop: (Thread::Queue queue) -> void
|
|
283
|
+
def drive_fiber: (Class task_class, TaskWrapper wrapper, Thread::Queue queue) -> void
|
|
284
|
+
def drive_fiber_loop: (Fiber fiber, Class task_class, TaskWrapper wrapper, Thread::Queue queue, ?untyped resume_value) -> void
|
|
285
|
+
def handle_dependency: (Class dep_class, Symbol method, Fiber fiber, Class task_class, TaskWrapper wrapper, Thread::Queue queue) -> void
|
|
286
|
+
def resume_fiber: (Fiber fiber, untyped value, Thread::Queue queue) -> void
|
|
287
|
+
def resume_fiber_with_error: (Fiber fiber, Exception error, Thread::Queue queue) -> void
|
|
288
|
+
def start_dependency: (Class dep_class, TaskWrapper dep_wrapper, Thread::Queue queue) -> void
|
|
289
|
+
def complete_task: (Class task_class, TaskWrapper wrapper, untyped result) -> void
|
|
290
|
+
def fail_task: (Class task_class, TaskWrapper wrapper, Exception error) -> void
|
|
291
|
+
def execute_clean_task: (Class task_class, TaskWrapper wrapper) -> void
|
|
292
|
+
def setup_clean_thread_locals: () -> void
|
|
293
|
+
def setup_run_thread_locals: () -> void
|
|
294
|
+
def teardown_thread_locals: () -> void
|
|
295
|
+
def start_output_capture: (Class task_class) -> void
|
|
296
|
+
def stop_output_capture: () -> void
|
|
297
|
+
def store_fiber_context: (Fiber fiber, Class task_class, TaskWrapper wrapper) -> void
|
|
298
|
+
def get_fiber_context: (Fiber fiber) -> Array[untyped]?
|
|
299
|
+
def task_duration_ms: (Class task_class) -> Float?
|
|
297
300
|
end
|
|
298
301
|
|
|
299
|
-
# Executor
|
|
302
|
+
# Executor orchestrates both run and clean phases of task execution
|
|
303
|
+
# Both run and clean phases use WorkerPool
|
|
300
304
|
class Executor
|
|
301
305
|
@registry: Registry
|
|
302
306
|
@completion_queue: Thread::Queue
|
|
303
|
-
@
|
|
307
|
+
@execution_facade: ExecutionFacade
|
|
304
308
|
@scheduler: Scheduler
|
|
305
309
|
@effective_worker_count: Integer?
|
|
306
|
-
@worker_pool: WorkerPool
|
|
307
|
-
@
|
|
310
|
+
@worker_pool: WorkerPool?
|
|
311
|
+
@saved_output_capture: TaskOutputRouter?
|
|
308
312
|
|
|
309
|
-
def self.execute: (Class root_task_class, registry: Registry,
|
|
310
|
-
def self.execute_clean: (Class root_task_class, registry: Registry,
|
|
311
|
-
def initialize: (registry: Registry,
|
|
313
|
+
def self.execute: (Class root_task_class, registry: Registry, execution_facade: ExecutionFacade) -> void
|
|
314
|
+
def self.execute_clean: (Class root_task_class, registry: Registry, execution_facade: ExecutionFacade) -> void
|
|
315
|
+
def initialize: (registry: Registry, execution_facade: ExecutionFacade, ?worker_count: Integer?) -> void
|
|
312
316
|
def execute: (Class root_task_class) -> void
|
|
313
317
|
def execute_clean: (Class root_task_class) -> void
|
|
314
318
|
|
|
315
319
|
private
|
|
316
320
|
|
|
317
|
-
def
|
|
318
|
-
def
|
|
319
|
-
def get_or_create_wrapper: (Class task_class) -> TaskWrapper
|
|
320
|
-
def execute_task: (Class task_class, TaskWrapper wrapper) -> void
|
|
321
|
+
def pre_start_leaf_tasks: () -> void
|
|
322
|
+
def enqueue_root_if_needed: (Class root_task_class) -> void
|
|
321
323
|
def run_main_loop: (Class root_task_class) -> void
|
|
322
324
|
def handle_completion: (Hash[Symbol, untyped] event) -> void
|
|
325
|
+
def enqueue_for_execution: (Class task_class) -> void
|
|
326
|
+
def skip_pending_dependents: (Class failed_task_class) -> void
|
|
327
|
+
def notify_skipped_tasks: () -> void
|
|
323
328
|
def enqueue_ready_clean_tasks: () -> void
|
|
324
329
|
def enqueue_clean_task: (Class task_class) -> void
|
|
325
|
-
def
|
|
326
|
-
def run_clean_main_loop: (Class root_task_class) -> void
|
|
330
|
+
def run_clean_main_loop: () -> void
|
|
327
331
|
def handle_clean_completion: (Hash[Symbol, untyped] event) -> void
|
|
328
332
|
def all_tasks_cleaned?: () -> bool
|
|
329
|
-
def
|
|
333
|
+
def with_display_lifecycle: (Class root_task_class) { () -> void } -> void
|
|
330
334
|
def setup_output_capture_if_needed: () -> bool
|
|
331
|
-
def teardown_output_capture: () -> void
|
|
332
|
-
def start_progress_display: () -> void
|
|
333
|
-
def stop_progress_display: () -> void
|
|
334
|
-
def create_default_execution_context: () -> ExecutionContext
|
|
335
|
-
def debug_log: (String message) -> void
|
|
336
335
|
def raise_if_any_failures: () -> void
|
|
337
|
-
def flatten_failures: (Array[TaskWrapper] failed_wrappers) -> Array[TaskFailure]
|
|
338
|
-
def wrap_with_task_error: (Class task_class, Exception error) -> TaskError
|
|
339
336
|
def raise_if_any_clean_failures: () -> void
|
|
340
|
-
def
|
|
337
|
+
def raise_if_any_failures_from: (Array[TaskWrapper] failed_wrappers, error_accessor: ^(TaskWrapper) -> StandardError?) -> void
|
|
338
|
+
def flatten_failures_from: (Array[TaskWrapper] failed_wrappers, error_accessor: ^(TaskWrapper) -> StandardError?) -> Array[TaskFailure]
|
|
339
|
+
def wrap_with_task_error: (Class task_class, Exception error) -> TaskError
|
|
341
340
|
def error_identity: (Exception error) -> Integer
|
|
341
|
+
def log_execution_started: (Class root_task_class) -> void
|
|
342
|
+
def log_execution_completed: (Class root_task_class, Time start_time) -> void
|
|
343
|
+
def log_error_detail: (Class task_class, Exception error) -> void
|
|
342
344
|
end
|
|
343
345
|
|
|
344
346
|
# TaskWrapper class for task execution
|
|
@@ -347,11 +349,11 @@ module Taski
|
|
|
347
349
|
attr_reader result: untyped
|
|
348
350
|
attr_reader error: StandardError?
|
|
349
351
|
attr_reader clean_error: StandardError?
|
|
350
|
-
attr_reader timing: TaskTiming?
|
|
351
352
|
|
|
352
353
|
@task: Task
|
|
353
354
|
@registry: Registry
|
|
354
|
-
@
|
|
355
|
+
@execution_facade: ExecutionFacade?
|
|
356
|
+
@args: Hash[Symbol, untyped]?
|
|
355
357
|
@result: untyped
|
|
356
358
|
@clean_result: untyped
|
|
357
359
|
@error: StandardError?
|
|
@@ -361,26 +363,30 @@ module Taski
|
|
|
361
363
|
@clean_condition: MonitorMixin::ConditionVariable
|
|
362
364
|
@state: Symbol
|
|
363
365
|
@clean_state: Symbol
|
|
364
|
-
@
|
|
366
|
+
@waiters: Array[Array[untyped]]
|
|
365
367
|
|
|
366
368
|
STATE_PENDING: Symbol
|
|
367
369
|
STATE_RUNNING: Symbol
|
|
368
370
|
STATE_COMPLETED: Symbol
|
|
369
371
|
STATE_FAILED: Symbol
|
|
372
|
+
STATE_SKIPPED: Symbol
|
|
370
373
|
|
|
371
|
-
def initialize: (Task task, registry: Registry, ?
|
|
374
|
+
def initialize: (Task task, registry: Registry, ?execution_facade: ExecutionFacade?, ?args: Hash[Symbol, untyped]?) -> void
|
|
372
375
|
def state: () -> Symbol
|
|
373
376
|
def pending?: () -> bool
|
|
374
377
|
def completed?: () -> bool
|
|
375
378
|
def failed?: () -> bool
|
|
376
|
-
def
|
|
379
|
+
def skipped?: () -> bool
|
|
377
380
|
def run: () -> untyped
|
|
378
381
|
def clean: () -> untyped
|
|
379
|
-
def
|
|
382
|
+
def reset!: () -> void
|
|
383
|
+
def run_and_clean: (?clean_on_failure: bool) ?{ () -> void } -> untyped
|
|
380
384
|
def get_exported_value: (Symbol method_name) -> untyped
|
|
385
|
+
def request_value: (Symbol method, Thread::Queue thread_queue, Fiber fiber) -> Array[untyped]
|
|
381
386
|
def mark_running: () -> bool
|
|
382
387
|
def mark_completed: (untyped result) -> void
|
|
383
388
|
def mark_failed: (StandardError error) -> void
|
|
389
|
+
def mark_skipped: () -> bool
|
|
384
390
|
def mark_clean_running: () -> bool
|
|
385
391
|
def mark_clean_completed: (untyped result) -> void
|
|
386
392
|
def mark_clean_failed: (StandardError error) -> void
|
|
@@ -391,89 +397,44 @@ module Taski
|
|
|
391
397
|
|
|
392
398
|
private
|
|
393
399
|
|
|
400
|
+
def with_args_lifecycle: [T] () { () -> T } -> T
|
|
394
401
|
def trigger_execution_and_wait: () -> void
|
|
395
402
|
def trigger_clean_and_wait: () -> void
|
|
396
|
-
def
|
|
397
|
-
def wait_for_clean_dependencies: () -> void
|
|
403
|
+
def trigger_and_wait: (state_accessor: ^() -> Symbol, condition: MonitorMixin::ConditionVariable, trigger: ^(ExecutionFacade) -> void) -> void
|
|
398
404
|
def check_abort!: () -> void
|
|
399
|
-
def
|
|
400
|
-
def
|
|
405
|
+
def ensure_execution_facade: () -> ExecutionFacade
|
|
406
|
+
def create_shared_context: () -> ExecutionFacade
|
|
407
|
+
def notify_skipped: () -> void
|
|
408
|
+
def update_progress: (Symbol state, ?error: Exception?) -> void
|
|
409
|
+
def update_clean_progress: (Symbol state, ?error: Exception?) -> void
|
|
410
|
+
def notify_state_change: (previous_state: Symbol?, current_state: Symbol, phase: Symbol) -> void
|
|
411
|
+
def notify_fiber_waiters_completed: (Array[Array[untyped]] waiters) -> void
|
|
412
|
+
def notify_fiber_waiters_failed: (Array[Array[untyped]] waiters, Exception error) -> void
|
|
401
413
|
end
|
|
414
|
+
end
|
|
402
415
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
@output: IO
|
|
410
|
-
@tasks: Hash[Class, TaskProgress]
|
|
411
|
-
@monitor: Monitor
|
|
412
|
-
@spinner_index: Integer
|
|
413
|
-
@renderer_thread: Thread?
|
|
414
|
-
@running: bool
|
|
415
|
-
@nest_level: Integer
|
|
416
|
-
@root_task_class: Class?
|
|
417
|
-
@tree_structure: Hash[Symbol, untyped]?
|
|
418
|
-
@section_impl_map: Hash[Class, Class]
|
|
419
|
-
@last_line_count: Integer
|
|
420
|
-
|
|
421
|
-
# Shared class methods
|
|
422
|
-
def self.section_class?: (Class klass) -> bool
|
|
423
|
-
def self.nested_class?: (Class child_class, Class parent_class) -> bool
|
|
424
|
-
def self.render_static_tree: (Class root_task_class) -> String
|
|
425
|
-
|
|
426
|
-
# Static tree renderer (internal class)
|
|
427
|
-
class StaticTreeRenderer
|
|
428
|
-
@task_index_map: Hash[Class, Integer]
|
|
429
|
-
|
|
430
|
-
def render: (Class root_task_class) -> String
|
|
431
|
-
|
|
432
|
-
private
|
|
433
|
-
|
|
434
|
-
def build_tree: (Class task_class, String prefix, bool is_impl, Set[Class] ancestors) -> String
|
|
435
|
-
def render_dependency_branch: (Class dep, String prefix, bool is_last, bool is_impl, Set[Class] ancestors) -> String
|
|
436
|
-
def get_task_number: (Class task_class) -> String
|
|
437
|
-
def colored_type_label: (Class klass) -> String
|
|
416
|
+
# Progress module
|
|
417
|
+
module Progress
|
|
418
|
+
module Layout
|
|
419
|
+
# Base class for progress display layouts
|
|
420
|
+
class Base < Execution::TaskObserver
|
|
438
421
|
end
|
|
439
422
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
attr_accessor error: Exception?
|
|
445
|
-
attr_accessor duration: Numeric?
|
|
446
|
-
attr_accessor is_impl_candidate: bool
|
|
447
|
-
|
|
448
|
-
def initialize: () -> void
|
|
423
|
+
# Tree layout for hierarchical task display
|
|
424
|
+
class Tree < Base
|
|
425
|
+
def initialize: (?output: IO, ?theme: Theme::Base?) -> void
|
|
426
|
+
def render_tree: () -> String
|
|
449
427
|
end
|
|
450
428
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
def task_registered?: (Class task_class) -> bool
|
|
456
|
-
def update_task: (Class task_class, state: Symbol, ?duration: Numeric?, ?error: Exception?) -> void
|
|
457
|
-
def task_state: (Class task_class) -> Symbol?
|
|
458
|
-
def start: () -> void
|
|
459
|
-
def stop: () -> void
|
|
460
|
-
|
|
461
|
-
private
|
|
429
|
+
# Simple layout for single-line progress display
|
|
430
|
+
class Simple < Base
|
|
431
|
+
def initialize: (?output: IO, ?theme: Theme::Base?) -> void
|
|
432
|
+
end
|
|
462
433
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
def render_final: () -> void
|
|
468
|
-
def build_tree_display: () -> Array[String]
|
|
469
|
-
def build_root_tree_lines: (Hash[Symbol, untyped] node, String prefix, Array[String] lines) -> void
|
|
470
|
-
def render_children: (Hash[Symbol, untyped] node, String prefix, Array[String] lines, Class parent_task_class, bool ancestor_selected) -> void
|
|
471
|
-
def format_tree_line: (Class task_class, TaskProgress? progress, bool is_impl, bool is_selected) -> String
|
|
472
|
-
def format_unknown_task: (Class task_class, ?bool is_selected) -> String
|
|
473
|
-
def spinner_char: () -> String
|
|
474
|
-
def type_label_for: (Class task_class, ?bool is_selected) -> String
|
|
475
|
-
def section_class?: (Class klass) -> bool
|
|
476
|
-
def nested_class?: (Class child_class, Class parent_class) -> bool
|
|
434
|
+
# Log layout for non-TTY environments
|
|
435
|
+
class Log < Base
|
|
436
|
+
def initialize: (?output: IO, ?theme: Theme::Base?) -> void
|
|
437
|
+
end
|
|
477
438
|
end
|
|
478
439
|
end
|
|
479
440
|
|
|
@@ -485,7 +446,6 @@ module Taski
|
|
|
485
446
|
|
|
486
447
|
private
|
|
487
448
|
|
|
488
|
-
def self.target_method_for: (Class task_class) -> Symbol
|
|
489
449
|
def self.extract_method_location: (Class task_class, Symbol method_name) -> [String, Integer]?
|
|
490
450
|
end
|
|
491
451
|
|
|
@@ -499,7 +459,7 @@ module Taski
|
|
|
499
459
|
|
|
500
460
|
attr_reader dependencies: Set[task_class]
|
|
501
461
|
|
|
502
|
-
def initialize: (Class task_class, Symbol target_method) -> void
|
|
462
|
+
def initialize: (Class task_class, ?Symbol target_method, ?Array[Symbol]? methods_to_analyze) -> void
|
|
503
463
|
def visit_class_node: (Prism::ClassNode node) -> untyped
|
|
504
464
|
def visit_module_node: (Prism::ModuleNode node) -> untyped
|
|
505
465
|
def visit_def_node: (Prism::DefNode node) -> untyped
|
|
@@ -507,19 +467,20 @@ module Taski
|
|
|
507
467
|
|
|
508
468
|
private
|
|
509
469
|
|
|
470
|
+
def follow_method_calls: () -> void
|
|
471
|
+
def collect_method_definitions: (Prism::ClassNode class_node) -> void
|
|
510
472
|
def within_namespace: (String? name) { () -> void } -> void
|
|
511
473
|
def in_target_class?: () -> bool
|
|
512
|
-
def in_impl_method?: () -> bool
|
|
513
474
|
def extract_constant_name: (untyped node) -> String?
|
|
475
|
+
def should_analyze_method?: (Symbol method_name) -> bool
|
|
476
|
+
def detect_method_call_to_follow: (Prism::CallNode node) -> void
|
|
477
|
+
def self_receiver?: (untyped receiver) -> bool
|
|
514
478
|
def detect_task_dependency: (Prism::CallNode node) -> void
|
|
515
|
-
def detect_impl_candidate: (untyped node) -> void
|
|
516
479
|
def extract_receiver_constant: (untyped receiver) -> String?
|
|
517
480
|
def resolve_and_add_dependency: (String constant_name) -> void
|
|
518
481
|
def resolve_constant: (String name) -> task_class?
|
|
519
482
|
def resolve_with_namespace_prefix: (String name) -> task_class?
|
|
520
483
|
def valid_dependency?: (task_class klass) -> bool
|
|
521
|
-
def is_parallel_task?: (task_class klass) -> boolish
|
|
522
|
-
def is_parallel_section?: (task_class klass) -> boolish
|
|
523
484
|
end
|
|
524
485
|
|
|
525
486
|
# DependencyGraph class for topological sorting and cycle detection
|
|
@@ -530,6 +491,7 @@ module Taski
|
|
|
530
491
|
|
|
531
492
|
def initialize: () -> void
|
|
532
493
|
def build_from: (Class root_task_class) -> self
|
|
494
|
+
def build_from_cached: (Class root_task_class) -> self
|
|
533
495
|
def sorted: () -> Array[Class]
|
|
534
496
|
def cyclic?: () -> bool
|
|
535
497
|
def strongly_connected_components: () -> Array[Array[Class]]
|
|
@@ -544,6 +506,35 @@ module Taski
|
|
|
544
506
|
private
|
|
545
507
|
|
|
546
508
|
def collect_dependencies: (Class task_class) -> void
|
|
509
|
+
def collect_cached_dependencies: (Class task_class) -> void
|
|
547
510
|
end
|
|
548
511
|
end
|
|
512
|
+
|
|
513
|
+
# Logging module
|
|
514
|
+
module Logging
|
|
515
|
+
module Events
|
|
516
|
+
EXECUTION_STARTED: String
|
|
517
|
+
EXECUTION_COMPLETED: String
|
|
518
|
+
TASK_STARTED: String
|
|
519
|
+
TASK_COMPLETED: String
|
|
520
|
+
TASK_FAILED: String
|
|
521
|
+
TASK_CLEAN_STARTED: String
|
|
522
|
+
TASK_CLEAN_COMPLETED: String
|
|
523
|
+
TASK_CLEAN_FAILED: String
|
|
524
|
+
TASK_SKIPPED: String
|
|
525
|
+
DEPENDENCY_RESOLVED: String
|
|
526
|
+
TASK_ERROR_DETAIL: String
|
|
527
|
+
TASK_OUTPUT: String
|
|
528
|
+
WORKER_POOL_ENQUEUED: String
|
|
529
|
+
EXECUTOR_TASK_COMPLETED: String
|
|
530
|
+
EXECUTOR_CLEAN_COMPLETED: String
|
|
531
|
+
OUTPUT_ROUTER_START_CAPTURE: String
|
|
532
|
+
OUTPUT_ROUTER_STOP_CAPTURE: String
|
|
533
|
+
OUTPUT_ROUTER_STOP_CAPTURE_UNREGISTERED: String
|
|
534
|
+
OUTPUT_ROUTER_DRAIN_PIPE: String
|
|
535
|
+
OUTPUT_ROUTER_STORE_LINES: String
|
|
536
|
+
OBSERVER_ERROR: String
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
end
|
|
549
540
|
end
|