Architecture Overview
Gears is designed around three core abstractions that work together to provide flexible task scheduling in simulation environments:
Core Concepts
1. Clocks - Time Abstraction
Clocks provide a unified interface for time, allowing you to work with either real system time or controllable virtual time for simulations.
2. Jobs - Task Definitions
Jobs represent the actual work to be performed. There are three types:
- Timed Jobs: Execute at regular intervals (e.g., every 10ms)
- ASAP Jobs: Execute as soon as possible (highest priority)
- Event Jobs: Execute when data arrives on a channel
3. Schedulers - Job Coordination
Schedulers manage when jobs should be executed, coordinating between the clock and the jobs. Schedulers can be configured to run in a single thread or in multiple threads.
Main Entry Points
The primary way users interact with Gears is through the every()
function, which creates different types of jobs:
Job Types
Timed Jobs - Execute at regular intervals
every(10ms) do dt plan!(agent) end
ASAP Jobs - Execute as soon as possible (highest priority)
every(asap) do process_urgent_task() end
Event Jobs - Execute when data arrives on a channel
events = Channel{String}(Inf) every(events) do event handle_event(event) end
Scheduler Control
every(scheduler,interval)
- Schedule tasksfor_next(clock, duration)
- Run the scheduler for a specific time periodupdate!(scheduler)
- Update the scheduler with the current time and execute all jobs that are scheduled to run within this time period
Example Usage
clock = MachineClock()
scheduler = TickedScheduler(clock, 1.0ms)
# Schedule agent planning every 10ms
every(scheduler,10ms) do dt
plan!(agent)
end
# Schedule environment updates every 1ms
every(scheduler,1ms) do dt
update!(environment)
end
# Handle urgent tasks as soon as possible
every(scheduler,asap) do
process_urgent_events()
end
# Run the simulation for 5 seconds
for_next(clock, 5s) do
update!(scheduler) # Process all scheduled jobs
end
This creates an asynchronous agent-environment interaction loop where both components run at their own frequencies, with urgent tasks handled immediately, all coordinated by the scheduler.
Architecture Principles
- Virtual Time First: All scheduling operates in virtual time, which can optionally sync with real time
- Job Autonomy: Jobs decide when to execute based on their own logic when invoked by the scheduler
- Scheduler Coordination: The scheduler coordinates between clocks and jobs, calling
progress!()
on jobs at appropriate times - Multiple Dispatch: Different job types and schedulers can have specialized behaviors through Julia's multiple dispatch system
Documentation Structure
- C4 Model - Complete C4 model showing all architecture levels
- Clocks - Detailed documentation on clock implementations
- Schedulers - Detailed documentation on scheduler implementations
- Jobs - Detailed documentation on job types and implementations