Tasks Event Gateway Extension
Tasks Event Gateway Extension
The Tasks Event Gateway (TEG) runs continuous background workers on Lucee Server. Each task is a CFML component (or .cfm template) that implements a repeating loop — you control sleep intervals, concurrency, and error backoff per task.
This is complementary to Quartz Scheduler and Quartz Scheduler vs Tasks Event Gateway: use Quartz for cron-style, calendar-based jobs; use TEG for always-on loops (queue polling, sync workers, heartbeat jobs).
Installation
Install via the Lucee Administrator, or see Extension Installation for all options (Dockerfile, deploy folder, env var, .CFConfig.json).
- Maven GAV:
org.lucee:tasks-extension - Extension ID:
947C02B0-7AE4-4054-938A8E059DD7625A - Source: github.com/lucee/task-event-gateway
- Downloads: download.lucee.org
Since extension 1.1.0.0, installing the
.lexfile does not create a gateway instance. You must register one manually (below).
Quick start
- Install the extension.
- Add a gateway instance (CFConfig or Administrator).
- Create
core/tasks/MyWorker.cfcextendingorg.lucee.cfml.Task. - Restart the gateway (or set
startupMode: automaticand restart Lucee). - Watch the configured log for
Tasks Event Gateway:lines.
Gateway instance (.CFConfig.json)
{
"gateways": {
"my-task": {
"cfcPath": "org.lucee.cfml.TasksGateway",
"listenerCFCPath": "",
"startupMode": "automatic",
"custom": {
"package": "core.tasks",
"templatePath": "",
"templatePathRecursive": true,
"checkForChangeInterval": 10,
"checkForChangeNoMatchInterval": 60,
"settingLocation": "",
"checkForChangeSettingInterval": 0,
"logName": "application"
},
"readOnly": "true"
}
}
}
In the Administrator: Services → Event Gateways → Add Gateway → type Tasks.
| Custom setting | Purpose |
|---|---|
package |
Dotted package scanned for Task/Listener CFCs (core.tasks → /core/tasks/) |
templatePath |
Optional folder of .cfm tasks (webroot path, mapping, or absolute path) |
templatePathRecursive |
Scan subfolders of templatePath (default true) |
checkForChangeInterval |
Seconds between reload checks for known task files |
checkForChangeNoMatchInterval |
Seconds between checks for non-task files in the scan path |
settingLocation |
Cache name for shared pause state across servers |
checkForChangeSettingInterval |
Poll interval for pause changes from other servers (0 = off) |
logName |
Lucee log file for gateway output |
Gateway instance values override environment variables and JVM system properties. See Environment Variables / System Properties for Lucee for the TASKS_EVENT_GATEWAY_* names (e.g. TASKS_EVENT_GATEWAY_PACKAGE, TASKS_EVENT_GATEWAY_CHECKFORCHANGENOMATCHINTERVAL).
Activator
By default the gateway uses org.lucee.cfml.tasks.Activator, whose active() always returns true. Point tasks.event.gateway.activator (or TASKS_EVENT_GATEWAY_ACTIVATOR) at your own CFC to disable the gateway during maintenance or when this node is not the cluster leader.
Creating a task (CFC)
component extends="org.lucee.cfml.Task" {
property name="concurrentThreadCount" type="numeric" default=1;
property name="howLongToSleepAfterTheCall" type="numeric" default=5000;
property name="howLongToSleepAfterTheCallWhenError" type="numeric" default=60000;
public void function invoke(
required string id,
required numeric iterations,
required numeric errors,
numeric lastExecutionTime,
date lastExecutionDate,
struct lastError
) {
// worker logic here
}
}
Task properties (all optional — defaults come from the base component):
| Property | Default | Meaning |
|---|---|---|
concurrentThreadCount |
1 |
Parallel threads for this task |
howLongToSleepBeforeTheCall |
0 |
ms before each invocation |
howLongToSleepAfterTheCall |
0 |
ms after success |
howLongToSleepAfterTheCallWhenError |
60000 |
ms after exception (back off to avoid log storms) |
howLongToWaitForTaskOnStop |
10000 |
Grace period on gateway stop |
forceStop |
false |
Force-terminate thread after grace period |
The gateway hot-reloads task CFCs when their file timestamp changes (interval controlled by checkForChangeInterval).
.cfm-based tasks
Set templatePath and add metadata to a comment block at the top of each template:
<!---
@task "Legacy cron job"
@concurrentThreadCount 1
@howLongToSleepAfterTheCall 5000
--->
Templates run as internal requests (Application.cfc applies). Execution context is passed via url.id, url.iterations, url.errors, url.lastExecutionTime, url.lastExecutionDate, and url.lastError.
Listeners
Components extending org.lucee.cfml.Listener in the same package receive lifecycle callbacks:
onExecutionStart— beforeinvoke()onExecutionEnd— after successfulinvoke()onError— wheninvoke()throws
Filter tasks with allow and deny (comma-separated, * and ? wildcards; deny wins):
property name="allow" type="string" default="*Queue*,MyWorker";
property name="deny" type="string" default="*Test*";
Runtime control (sendGatewayMessage)
Use SendGatewayMessage() with the gateway instance ID as the first argument:
sendGatewayMessage("my-task", { action: "state" });
info = sendGatewayMessage("my-task", { action: "info" });
dump(deserializeJSON(info));
sendGatewayMessage("my-task", { action: "pause", task: "core.tasks.MyWorker" });
sendGatewayMessage("my-task", { action: "resume", task: "core.tasks.MyWorker" });
| Action | Description |
|---|---|
state |
Gateway state string (running, stopped, …) |
info |
JSON snapshot of tasks, thread instances, and timing |
pause |
Pause a task by full component/template name |
resume |
Resume a paused task |
With settingLocation set to a shared cache, pause state survives restarts and propagates to other servers when checkForChangeSettingInterval is enabled.
Multiple gateway instances
You can register several TEG instances (different IDs) — for example one per application package or one for CFC tasks and one for .cfm templates. Each instance has its own scan path, log, and task pool. Use distinct settingLocation cache key prefixes via the gateway ID when sharing pause state.
Troubleshooting
- Gateway won't start — Check activator; read the log named in
logName; confirmorg.lucee.cfml.TasksGatewayis the gateway CFC path. - Task missing — Verify
extends="org.lucee.cfml.Task", package name, and component mapping. - Template ignored —
@taskmetadata required; path must be undertemplatePathand reachable internally. - Stale code — Wait for
checkForChangeIntervalor touch the file; ensure Lucee template inspection is not caching stale gateway drivers in older versions. - Runaway errors — Raise
howLongToSleepAfterTheCallWhenErroron the task.
See also
- Event Gateways — gateway lifecycle and architecture
- Quartz Scheduler — cron and calendar scheduling
- Extension README — full reference including build instructions