Task Queue

True\TaskQueue offloads PHP work to a background runner — drop a script in app/tasks/, call addTask(), return the response. A separate worker process picks the task up within a couple of seconds. Pair it with TaskScheduler when you need future-dated or recurring runs instead.

Setup

Construct the queue in init.php. The SQLite database path is the only required argument and the file is created on first use:

$App->TaskQueue = new True\TaskQueue(BP . '/data/tasks.sqlite');

If task scripts need access to objects from your app, pass them through:

$App->TaskQueue->passObjects(['App' => $App]);

The objects become available inside the task script as variables with the names you supplied (above, $App).

Queue a task

From a controller or route handler, call addTask() with a script name and an associative array of values to pass:

try {
    $App->TaskQueue->addTask('task.php', ['var1' => 1]);
} catch (Exception $e) {
    trigger_error($e->getMessage(), 256);
}

By default a bare filename is resolved against BP/app/tasks/. If you pass a leading slash, it's used as-is so you can point at scripts in arbitrary locations.

The task script

The array of values you pass to addTask() is extracted into the script's local scope. Any objects you registered via passObjects() are also available.

<?php
// app/tasks/task.php

$config = $App->getConfig('contact-email-info.ini');

$Mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
    $Mail->isSMTP();
    $Mail->Host       = $config->host;
    $Mail->SMTPAuth   = true;
    $Mail->Username   = $config->username;
    $Mail->Password   = $config->password;
    $Mail->SMTPSecure = 'tls';
    $Mail->Port       = $config->port;
    $Mail->setFrom($config->from_email, $config->from_name);
    $Mail->addAddress($config->to_email, $config->to_name);
    $Mail->isHTML(true);
    $Mail->Subject = $config->subject;
    $Mail->Body    = $taskData->message;
    $Mail->send();
} catch (Exception) {
    error_log("Mailer Error: {$Mail->ErrorInfo}", 3, BP.'/php-error.log');
}

Running the worker

You want the runner to wake up every 2–5 seconds. Cron only goes down to 1 minute, so a systemd service is the recommended approach. The library ships a service file at vendor/truecastdesign/true/workers/taskRunner.service.

Install the service

Copy the file to /etc/systemd/system/taskRunner.service and edit the ExecStart line for your PHP binary and project path:

ExecStart=/usr/local/bin/ea-php82 /home/username/vendor/truecastdesign/true/workers/taskRunner.php

As root, enable and start it:

systemctl daemon-reload
systemctl enable --now taskRunner.service

Check / stop / restart

systemctl status taskRunner.service     # is it running?
systemctl restart taskRunner.service    # restart it
systemctl stop taskRunner.service       # stop until next boot
systemctl disable taskRunner.service    # also stop it auto-starting on boot

If you edit the unit file after installing, systemctl daemon-reload picks up the change.

Debugging a task script

Run the worker manually in your shell. Adjust the PHP binary and path for your environment:

/usr/local/bin/ea-php82 /home/username/vendor/truecastdesign/true/workers/taskRunner.php

Shared hosting without systemd

If you don't have root access, you can keep the runner alive with watch over SSH:

nohup watch -n 2 /usr/local/bin/ea-php82 /home/username/vendor/truecastdesign/true/workers/taskRunner.php > /home/username/logs/taskqueue.log 2>&1 &

It's a fragile setup — the connection drops, the runner dies — but it works in a pinch.