Class: Kernai::TaskScheduler
- Inherits:
-
Object
- Object
- Kernai::TaskScheduler
- Defined in:
- lib/kernai/task_scheduler.rb
Overview
Executes the tasks stored in a Context, respecting dependencies and parallelism flags. The scheduler is intentionally dumb: it has no knowledge of LLMs, agents or providers. A ‘runner` callable receives (task, context) and is expected to return the task result.
The scheduling strategy is read from ‘context.plan.strategy`:
-
“sequential” forces every ready task to run serially
-
“parallel” forces every ready task to run concurrently
-
“mixed” (default) honors each task’s own ‘parallel` flag
Defined Under Namespace
Classes: DeadlockError
Constant Summary collapse
- STRATEGIES =
%w[sequential parallel mixed].freeze
- DEFAULT_STRATEGY =
'mixed'
Instance Method Summary collapse
-
#initialize(context, runner) ⇒ TaskScheduler
constructor
A new instance of TaskScheduler.
-
#run ⇒ Object
Run all tasks until the graph is complete.
Constructor Details
#initialize(context, runner) ⇒ TaskScheduler
Returns a new instance of TaskScheduler.
21 22 23 24 25 |
# File 'lib/kernai/task_scheduler.rb', line 21 def initialize(context, runner) @context = context @runner = runner @strategy = resolve_strategy(context.plan&.strategy) end |
Instance Method Details
#run ⇒ Object
Run all tasks until the graph is complete. Returns the final task_results hash.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/kernai/task_scheduler.rb', line 29 def run loop do ready = ready_tasks if ready.empty? pending = @context.tasks.reject(&:done?) raise DeadlockError, "Tasks could not complete: #{pending.map(&:id).join(', ')}" if pending.any? break end parallel, sequential = ready.partition { |t| effective_parallel?(t) } run_parallel(parallel) if parallel.any? run_sequential(sequential) if sequential.any? end @context.task_results end |