Skip to content

CodeIgniter 4

since: 1.8

runwisp/runwisp runs the CodeIgniter Tasks schedule under RunWisp. Your app/Config/Tasks.php stays as it is. php spark runwisp:work replaces the tasks:run cron entry, and every run gets a log, an exit code and a duration in the web UI.

It works with CodeIgniter 4.6 and later, with codeigniter4/tasks 1.x.

Terminal window
composer require runwisp/runwisp codeigniter4/tasks

Composer asks to allow the runwisp/runwisp plugin, which downloads the runwisp binary. CodeIgniter finds the package’s commands on its own.

Remove the tasks:run line from your crontab, and start the worker instead:

Terminal window
php spark runwisp:work

Keep it running the way you keep a queue worker running: a systemd unit, a Supervisor program or your container’s command. On startup it prints where to find RunWisp:

RunWisp dashboard: http://127.0.0.1:9477, password: vendor/bin/runwisp password --data writable/runwisp

RunWisp keeps its database, run logs and socket in writable/runwisp.

runwisp:work reads the schedule from app/Config/Tasks.php, as tasks:run does:

app/Config/Tasks.php
<?php
namespace Config;
use App\Models\UserModel;
use CodeIgniter\Tasks\Config\Tasks as BaseTasks;
use CodeIgniter\Tasks\Scheduler;
use RunWisp\Task;
class Tasks extends BaseTasks
{
public function init(Scheduler $schedule)
{
$schedule->command('reports:send')->daily('3:00 am');
$schedule->call(#[Task(retry_attempts: 2)] static function () {
model(UserModel::class)->pruneInactive();
})->hourly()->named('prune-users');
}
}

Each task becomes a RunWisp task:

  • Name: the task’s named() name, else the name in its #[Task], else its action: the spark command (reports:send), the shell command, the event, the URL or the queue and job. A closure without a name is named after its file and line, and the worker warns, since moving the line starts a new run history. Give closures a named().
  • Schedule: the cron expression, in the app’s timezone (appTimezone in app/Config/App.php).
  • Overlap: singleInstance() sets on_overlap = "skip". Without it, RunWisp’s default applies: a run that comes while the last one is still going waits for it.

Tasks limited to other environments with environments() are left out.

Each run is php spark runwisp:run <name> in a new process, so a run gets a fresh app, and stopping it from the web UI stops the process. What the task returns goes to the run’s log: a command’s output, a shell command’s lines, a URL’s body. A command’s output shows up when the command ends. An exception fails the run with exit code 1 and the stack trace in its log.

Put #[RunWisp\Task] on the spark command’s class, or before a closure’s function, to add task keys such as retry_attempts, timeout and notify. The keys are named as in runwisp.toml:

app/Commands/SendReports.php
<?php
namespace App\Commands;
use CodeIgniter\CLI\BaseCommand;
use RunWisp\Task;
#[Task(retry_attempts: 3, timeout: '10m', notify: ['slack'])]
class SendReports extends BaseCommand
{
protected $group = 'App';
protected $name = 'reports:send';
protected $description = 'Sends the daily reports.';
public function run(array $params)
{
// ...
}
}

The first argument is the task name: #[Task('reports', retry_attempts: 3)]. The schedule comes from app/Config/Tasks.php, so cron and timezone are not accepted.

Extend the package’s config in app/Config/RunWisp.php:

app/Config/RunWisp.php
<?php
namespace Config;
use RunWisp\CodeIgniter\Config\RunWisp as BaseRunWisp;
class RunWisp extends BaseRunWisp
{
public ?int $port = 9500;
public array $config = [
'notifiers' => [
'slack' => ['type' => 'slack', 'webhook_url' => '${SLACK_WEBHOOK_URL}'],
],
'defaults' => ['keep_runs' => 100],
];
}

The properties are the SDK options: app, data, port, host, password, auth and binary. config takes the rest of a runwisp.toml, such as notifiers and defaults.

A property left null reads its RUNWISP_* env var, such as RUNWISP_PORT and RUNWISP_PASSWORD, so most apps need no config file.

php spark runwisp:check lists the tasks runwisp:work would run, with each schedule, next run and RunWisp options, and checks the config with RunWisp, without starting anything:

Terminal window
php spark runwisp:check

It exits with code 1 when RunWisp would reject the config, such as for a misspelled key, so you can run it in CI. See Check your tasks.

Start a run from the web UI, the TUI or runwisp run. To run a task outside RunWisp, without recording it:

Terminal window
php spark runwisp:run reports:send

See the PHP SDK for what happens with several copies of the worker, and when the worker stops.