-
Notifications
You must be signed in to change notification settings - Fork 0
Task Queue & Step Runner
Relevant source files
The Task Queue and Step Runner form the execution engine of Lodestar's job-discovery pipeline. While the pipeline defines the high-level logic (e.g., "scrape careers page"), the Task Queue provides durable persistence to ensure runs survive app restarts, and the Step Runner handles the telemetry projection of individual execution stages into the user's vault.
Lodestar uses a local SQLite database to manage a durable task queue. This implementation ensures that long-running pipeline operations are not lost if the application crashes or is closed mid-run.
Tasks within the SqliteQueue transition through several states defined in src-tauri/src/pipeline/queue.rs:
| State | Description |
|---|---|
pending |
The initial state for a NewTask. Ready to be picked up by the runner src-tauri/src/pipeline/queue.rs#81
|
claimed |
A task currently being processed. Atomically transitioned from pending via claim_nextsrc-tauri/src/pipeline/queue.rs#132
|
done |
Successfully completed tasks src-tauri/src/pipeline/queue.rs#142 |
dead |
Tasks that have exceeded MAX_ATTEMPTS or encountered a terminal failure src-tauri/src/pipeline/queue.rs#151
|
- Atomicity (
claim_next): To prevent race conditions,claim_nextqueries for the oldestpendingtask and immediately updates its state toclaimedwhile incrementing theattemptscounter within a single database lock src-tauri/src/pipeline/queue.rs#106-138 - Exponential Backoff: Failed tasks are rescheduled with a delay calculated by
backoff_delay(attempt), which caps at 5 minutes (300 seconds) src-tauri/src/pipeline/queue.rs#61-63 - Crash Recovery: Upon opening the database, the queue automatically resets any tasks stuck in the
claimedstate back topending. This ensures that if the worker dies mid-step, the run resumes on next launch src-tauri/src/pipeline/queue.rs#84 - Run Abort (
discard_run_tasks): Outstanding tasks (pendingorclaimed) for a specificrun_idcan be deleted to halt a pipeline run without losing the history of completed (done) or failed (dead) steps src-tauri/src/pipeline/queue.rs#178-187
The following diagram maps the Natural Language concepts of the queue to the specific Rust structs and SQLite schema.
Task Queue Entity Mapping
flowchart TD
subgraph subGraph1 ["Code Entity Space (src-tauri/src/pipeline/queue.rs)"]
NewTask["struct NewTask { run_id, stage, payload }"]
QueuedTask["struct QueuedTask { id, attempts, ... }"]
SqliteQueue["struct SqliteQueue { conn: Mutex }"]
SQL["CREATE TABLE tasks (state, last_error, ...)"]
end
subgraph subGraph0 ["Natural Language Space"]
A["A New Work Item"]
B["An Active Task"]
C["Durable Storage"]
end
A --> NewTask
B --> QueuedTask
C --> SqliteQueue
SqliteQueue --> SQL
NewTask --> SQL
SQL --> QueuedTask
Sources: src-tauri/src/pipeline/queue.rs#22-40src-tauri/src/pipeline/queue.rs#65-87
The Step Runner executes individual pipeline stages and projects telemetry back into the Obsidian vault. It acts as the bridge between the execution clients (Scrapers, LLMs) and the durable Markdown records in the checks/ directory.
Every execution stage results in a Step record. These records are appended to the Markdown frontmatter of a "Check" note in the vault via record_stepsrc-tauri/src/pipeline/runner.rs#113-135
The runner uses a Builder Pattern for outcomes:
-
StepOutcome::ok(cost): Records success and any financial/credit cost src-tauri/src/pipeline/runner.rs#62-71 -
StepOutcome::failed(error, cost): Records failure message and partial costs src-tauri/src/pipeline/runner.rs#74-83 -
StepOutcome::warned(warnings, cost): Records successful completion but with noted issues src-tauri/src/pipeline/runner.rs#87-97 -
with_cache(read, write): Appends LLM prompt caching telemetry to an existing outcome src-tauri/src/pipeline/runner.rs#103-107
The run_scrape_step function is a primary entry point for the runner. It orchestrates the following:
- Timestamping: Captures
started_atusingnow_iso()src-tauri/src/pipeline/runner.rs#151 - Execution: Calls the
Scraper::fetchmethod src-tauri/src/pipeline/runner.rs#152 - Recording: Automatically converts
ScrapeResultcredits into aSteprecord in the vault src-tauri/src/pipeline/runner.rs#155-159 - Error Handling: If the scrape fails, it records the failure before propagating the
ScrapeErrorsrc-tauri/src/pipeline/runner.rs#168-172
The src-tauri/src/check.rs module handles the actual serialization of these steps into Markdown.
Step to Markdown Projection
flowchart LR
subgraph subGraph2 ["Vault Structure"]
StepsList["steps: #91; { stage, status, cost } #93;"]
end
subgraph subGraph1 ["Persistence (check.rs)"]
RS["record_step()"]
AS["append_step()"]
CheckNote["Check Markdown Note"]
end
subgraph subGraph0 ["Execution (runner.rs)"]
SO["StepOutcome"]
SI["StepIdentity"]
end
SO --> RS
SI --> RS
RS --> AS
AS --> CheckNote
CheckNote --> StepsList
Sources: src-tauri/src/pipeline/runner.rs#113-135src-tauri/src/check.rs#151-158src-tauri/src/check.rs#98-135
The Step struct is the unit of telemetry stored in the vault src-tauri/src/check.rs#12-41:
| Field | Description |
|---|---|
stage |
The name of the pipeline stage (e.g., jd-scrape). |
class |
The type of work (e.g., scrape, llm, script). |
status |
ok, failed, or warning. |
cost |
ScrapingBee credits or OpenRouter micro-USD. |
cache_read_tokens |
Telemetry showing prompt cache hits (OpenRouter). |
warnings |
A list of non-fatal issues encountered during the step. |
Sources: src-tauri/src/pipeline/runner.rs#1-172src-tauri/src/pipeline/queue.rs#1-188src-tauri/src/check.rs#1-158