PHPackages                             citomni/jobrunner - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. citomni/jobrunner

ActiveLibrary[Framework](/categories/framework)

citomni/jobrunner
=================

Small DB-backed job runner for CitOmni: HTTP/UI-started long-running jobs executed by CLI workers with status, steps, logs, heartbeat, and results.

v1.0.0.0(1mo ago)00MITPHPPHP ^8.2

Since Jun 14Pushed 1mo agoCompare

[ Source](https://github.com/citomni/jobrunner)[ Packagist](https://packagist.org/packages/citomni/jobrunner)[ Docs](https://github.com/citomni/jobrunner)[ GitHub Sponsors](https://github.com/LarsGMortensen)[ Fund](https://ko-fi.com/)[ RSS](/packages/citomni-jobrunner/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

CitOmni JobRunner
=================

[](#citomni-jobrunner)

DB-backed long-running job execution for CitOmni.

`citomni/jobrunner` is a small CitOmni provider package for explicit long-running jobs that are started from HTTP/UI, persisted in the database, executed by a separate CLI worker, and observed through status, progress, logs, heartbeat, errors, and result data.

The package is deliberately scoped. It is not a generic queue system, not a daemon, not a scheduler, and not a web-based shell for arbitrary commands. Applications start registered and validated job types; the actual workflow lives in PHP job handlers.

Typical use cases include DevKit workflows, imports, exports, deploy steps, rebuilds, report generation, and other explicit administration or developer tasks that are too slow, risky, or verbose to run inside a browser request.

---

Highlights
----------

[](#highlights)

- Runs long application-defined jobs outside the HTTP request lifecycle.
- Starts jobs from HTTP, CLI, or other app code through `StartJob`.
- Executes handlers through the CitOmni CLI worker command.
- Exposes job status, progress, logs, results, and errors through `GetJobStatus`.
- Supports cooperative cancellation through `CancelJob`.
- Persists jobs and logs in MySQL using explicit repository-owned SQL.
- Supports active-job locks to prevent duplicate jobs where needed.
- Uses CitOmni's provider model; no custom discovery or framework magic. The rabbit stays in the hat.

---

Documentation
-------------

[](#documentation)

Start here:

- [JobRunner usage guide](https://github.com/citomni/docs/blob/main/how-to/jobrunner-usage.md)
- [End-to-end smoke test](https://github.com/citomni/docs/blob/main/how-to/jobrunner-end-to-end-smoke-test.md)

Long-form documentation lives in the separate [`citomni/docs`](https://github.com/citomni/docs) repository. This package README stays focused on installation, runtime shape, and the public surface. It is a README, not a furniture warehouse.

---

Requirements
------------

[](#requirements)

- PHP 8.2+
- Composer
- CitOmni application using `citomni/kernel`
- CitOmni CLI mode for worker execution
- A database connection supplied through `citomni/infrastructure`

`citomni/jobrunner` must be installed as a Composer dependency. Do not copy package source into an application.

---

Installation
------------

[](#installation)

```
composer require citomni/jobrunner
```

Install the database schema from the package:

```
sql/citomni_jobrunner.sql

```

The schema creates the JobRunner job and log tables used by the repository layer.

---

What this package provides
--------------------------

[](#what-this-package-provides)

### Job lifecycle

[](#job-lifecycle)

- Job creation through `StartJob`
- DB-backed queued/running/cancel\_requested/succeeded/failed/cancelled status tracking
- Atomic worker claiming
- Worker token validation
- Heartbeat timestamps
- Step key, label, index, and total tracking
- Final result persistence
- Error summary persistence
- Cooperative cancellation through `CancelJob`
- Status/read model through `GetJobStatus`

### CLI worker execution

[](#cli-worker-execution)

- CLI command for running one queued job
- Detached worker launch support
- Handler dispatch by registered job type
- Deterministic worker boundary error handling

### Logging and progress

[](#logging-and-progress)

- Job-level logs
- Structured log levels and streams
- stdout/stderr-oriented log streams where relevant
- Incremental log polling via `afterSeq` / `last_log_seq`
- Bounded log retrieval for UI polling

### Provider integration

[](#provider-integration)

- Service registration through `MAP_COMMON`
- Default configuration through `CFG_COMMON`
- CLI command registration through `COMMANDS_CLI`
- No package-specific runtime config discovery
- No parallel merge system

---

What this package owns
----------------------

[](#what-this-package-owns)

`citomni/jobrunner` owns the generic lifecycle of long-running jobs.

That includes:

- The job record
- Job status
- Job payload persistence
- Job result persistence
- Job error state
- Job log persistence
- Worker token hash
- Worker claim state
- Current step state
- Heartbeat timestamps
- Cancellation request state
- Handler lookup by registered job type
- CLI worker command

This ownership model keeps the runner useful across packages without turning it into the package that knows what every job actually does.

---

What this package does not own
------------------------------

[](#what-this-package-does-not-own)

`citomni/jobrunner` is intentionally not a universal queue, shell, or workflow framework.

It does **not** own:

- DevKit Create App workflow logic
- Commerce import/export logic
- Deploy workflow logic
- Composer-specific workflow logic
- Git-specific workflow logic
- Application-specific business logic
- Arbitrary command execution from HTTP
- Permanent daemon workers
- Multiple queue backends
- Scheduled jobs
- Automatic retry policies
- Distributed worker orchestration
- A polished generic administration UI

This package makes long-running workflows observable and safe to execute outside HTTP requests. It should not become a background-processing theme park with surprise rides.

---

Runtime model
-------------

[](#runtime-model)

A typical flow:

```
HTTP Controller / UI
  -> validates input
  -> creates job through StartJob
  -> starts detached CLI worker
  -> returns job id / status URL

CLI Worker
  -> claims job
  -> resolves registered handler
  -> runs workflow
  -> writes status, logs, steps, heartbeat, and result

HTTP Status UI
  -> polls GetJobStatus
  -> displays progress, logs, error, or result
  -> may request cancellation through CancelJob

```

`citomni/jobrunner` knows how to run a registered job. It does not know what creating an app, importing products, or publishing a deploy means.

Examples:

```
citomni/devkit
  -> devkit.create_app

citomni/commerce
  -> commerce.import_products
  -> commerce.export_feed

```

---

Public operations
-----------------

[](#public-operations)

The package exposes the main runtime surface as transport-agnostic operations.

### `StartJob`

[](#startjob)

Creates a queued job and launches the worker.

Use it from controllers, commands, or app/package orchestration code after input has been validated by the adapter layer.

### `GetJobStatus`

[](#getjobstatus)

Reads one job and a bounded log slice for polling UIs.

Typical UI behavior:

```
GET job status
render status, progress, and logs
store last_log_seq
next poll requests logs after last_log_seq

```

### `CancelJob`

[](#canceljob)

Requests cooperative cancellation.

Implemented behavior:

```
queued           -> cancelled
running          -> cancel_requested
cancel_requested -> already_cancel_requested
succeeded        -> already_terminal
failed           -> already_terminal
cancelled        -> already_terminal
missing          -> not_found

```

A running job is not killed directly. The handler must check `JobContext::isCancellationRequested()` between meaningful steps and return cleanly. The worker then finalizes the job as `cancelled`.

---

Registering job handlers
------------------------

[](#registering-job-handlers)

Applications and consumer packages register explicit job types in CitOmni config.

Example app config overlay:

```
