# apexl/io-jobs

Job queue module for Cygnus (`apexl/io`). Provides a database-backed queue of deferred tasks with locking, retry, failure handling, and a console runner.

## What it provides

- **`QueueJob` entity** — a queued job row (`handler`, contents, lock state, `run_after`, failure tracking) on the `job_queue` table.
- **`TaskRunnerService`** — pulls batches of due tasks and runs each: `lock()` → `run()` → `markProcessed()` → `unlock()`, catching and routing failures to `handleFailure()`. Skips already-locked tasks.
- **`QueuedTaskFinderInterface`** (default `QueuedTaskFinderDb`) — finds and batches due tasks from the DB.
- **Task contracts** — `QueueTaskInterface` (a runnable unit: `lock`/`unlock`/`run`/`markProcessed`/`handleFailure`/`isLocked`), `QueueTaskHandlerInterface` (the work: `run()` + `handleFailure()`), and `RetryableTaskHandlerInterface` for handlers that should be retried.
- **`QueueJobTask`** — adapter wrapping a `QueueJob` as a `QueueTaskInterface`.
- **`jobs:run` console command** (`RunJobsCommand`) — processes the queue with an optional `--limit` (default 10). Registered via the `ConsoleCommands` hook.
- **`QueueProcessController`** — HTTP entry point to trigger queue processing.

## Installation

```
composer require apexl/io-jobs
```

Hosted on Bitbucket (not the `packages.apexl` Satis registry). Register the module in the host's `config/modules.php`:

```php
apexl\Io\modules\jobs\jobsModule::class,
```

Migrations install and evolve the `job_queue` table (including the `run_after` delayed-execution column).

## Key concepts / usage

A producer enqueues a `QueueJob` referencing a handler that implements `QueueTaskHandlerInterface` (or `RetryableTaskHandlerInterface`). A scheduled invocation of the runner drains the queue:

```
php bin/console jobs:run --limit=20
```

Run it on a cron. `TaskRunnerService` locks each job before running so concurrent runners don't double-process, and routes thrown exceptions to the handler's `handleFailure()` for retry/dead-lettering. The `run_after` column lets jobs be scheduled for future execution.

## Conventions

`services.php` autowires `QueuedTaskFinderInterface` → `QueuedTaskFinderDb` — swap the binding to change task discovery. Tests live in `tests/` (PHPUnit).
