Scheduled Tasks - edmozley/freeitsm GitHub Wiki
Scheduled tasks (cron jobs)
Some things in FreeITSM cannot happen while somebody is looking at a screen. An SLA breaches at 3am. A contract expires in 30 days. A developer comments on a Jira issue and nobody is watching. For those, FreeITSM needs a small job that wakes up on a timer.
None of them are set up for you. A fresh install has no scheduled tasks at all, and the features that depend on them fail silently โ nothing errors, nothing appears in a log, the feature simply never happens. This page lists every one, what breaks without it, and how to set it up on Windows and Linux.
โ ๏ธ Silent is the important word. A tracker whose status never changes looks exactly like a tracker where nothing has happened. An SLA that never breaches looks like good service. If a time-based feature "doesn't seem to work", check this page first.
The nine jobs
| Job | What it does | What breaks without it | Suggested interval |
|---|---|---|---|
cron/integration_poll.php |
Asks Jira (and other issue trackers) what has changed | Issue status never updates and comments never come back โ see Issue trackers | every 5 minutes |
cron/sla_breach_check.php |
Checks open tickets against their SLA targets | SLA warning and breach notifications are never sent | every 5 minutes |
cron/webhook_deliveries.php |
Delivers queued outbound webhooks, with retries | Webhooks fired by workflows sit in the queue and never send | every 1 minute |
cron/workflow_scheduled.php |
Fires time-based workflow triggers | Rules like "this contract expires in 30 days" never run | every 5 minutes |
cron/task_recurrence.php |
Creates the next occurrence of tasks that repeat on a fixed schedule, once work on it can start | Fixed-schedule repeats never appear. Repeats set to after completion are unaffected โ see the note below | once a day |
cron/calendar_sync_pull.php |
Reads changes back out of analysts' calendars - Microsoft 365 and CalDAV servers alike | Moving or deleting a synced appointment in a calendar never reaches FreeITSM. The outbound half still works โ see Ticket calendar sync | every 5 minutes |
cron/attachment_extract.php |
Reads the text out of PDFs and scanned documents so they can be searched | Nothing immediately โ see the note below | every 5 minutes |
scripts/documents_maintenance.php |
Reads the text out of files attached through Documents, and collects documents whose record has been deleted | Nothing immediately โ see the note below | every 5 minutes |
scripts/directory_sync.php --all |
Imports people from every enabled directory (LDAP / Active Directory) and address book (CardDAV) โ see Directory sync and Contact details | Nothing immediately, and nothing loudly. People are imported only when somebody presses Run on the source's own page, so a new starter added to your directory on Monday does not exist in FreeITSM until a human remembers | once or twice a day |
Two of these are not in
cron/.scripts/documents_maintenance.phpandscripts/directory_sync.phplive with the other command-line scripts, so listing thecron/folder will not show them. They are scheduled jobs in every other respect.
The people import was missing from this page until 1.8.0, which is worth saying plainly: it has been schedulable since directory sync shipped, and anyone running a directory had no way to find that out from the documentation. If you use LDAP or Active Directory today and have been pressing Run by hand, this is the job you wanted.
--allmeans every enabled source of either kind. It skips anything switched off, and skips OIDC providers entirely โ they sign people in and import nobody. Add--previewto have it report what it would do and write nothing, which is the sensible way to see what a schedule is about to start doing on its own. A single source can be run on its own with--provider=<id>.
The first four each have a detailed setup document in the docs/ folder of the application: integration-poll-cron-setup.md, sla-cron-setup.md, webhook-cron-setup.md and workflow-scheduled-cron-setup.md.
An occurrence appears when work on it can START, not when it falls due. A repeat keeps the gap between starting and being due, so a task that needs a fortnight appears a fortnight before its due date and a task with no start date appears on the day. This is why the job runs daily rather than hourly, and why the board only ever holds work you could actually be doing: the lead time is the task's own duration, which you have already given it, rather than a number to configure.
Only half of recurring tasks needs this job. A task set to repeat after completion makes its next occurrence inside the request that completed the last one, so it works on an installation with no scheduled tasks at all. Only fixed schedule repeats โ the ones that arrive on their dates whether or not the previous one was finished โ need this job running. The calendar draws future fixed-schedule occurrences faintly before they exist, so you can see the plan either way, but the actual tasks are created by this job. See Tasks.
The attachment job is the odd one out, deliberately. It is the only one whose absence is not silent failure. Without it, waiting documents are still read โ a few at a time, whenever somebody is using FreeITSM โ so attachment searching works on an installation with no scheduled tasks at all. The job just keeps up with a busy service desk rather than trickling. Both behaviours can be turned off in Tickets โ Settings โ Indexing, and neither does anything until a document reader is set up under System โ Integrations โ Apache Tika. See Attachment text extraction.
The documents job is the other one whose absence is not silent failure. Attaching a file reads it there and then, with a few seconds to do it in โ right for one file, useless for somebody who has just attached fifty warranty PDFs, which then sit unread until the next upload nudges the queue. The job clears that backlog. Its second half matters more quietly: a document attached to a contract survives the contract being deleted, because the link can point at any kind of record and so no database rule can clean it up. The document becomes invisible immediately โ every permission check asks whether its parent still exists โ but the file stays on the disk forever. Nothing leaks and nothing is lost without this job; you get prompt searching and disk that does not slowly fill with files nobody can reach. See Attached documents.
Which do I actually need?
Only the ones matching the features you use. If you have no issue tracker connected, the tracker poll does nothing useful. If you have never written a workflow, the scheduled-workflow job has nothing to fire. If in doubt, set them all up โ an unused job costs a second of CPU and prints one line saying it had nothing to do.
Windows (Task Scheduler)
Run these in a Command Prompt opened as Administrator. Adjust the two paths if your PHP or FreeITSM lives elsewhere.
schtasks /create /tn "FreeITSM Tracker Poll" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\integration_poll.php" /sc minute /mo 5 /ru SYSTEM
schtasks /create /tn "FreeITSM SLA Breach Check" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\sla_breach_check.php" /sc minute /mo 5 /ru SYSTEM
schtasks /create /tn "FreeITSM Webhooks" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\webhook_deliveries.php" /sc minute /mo 1 /ru SYSTEM
schtasks /create /tn "FreeITSM Scheduled Workflows" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\workflow_scheduled.php" /sc minute /mo 5 /ru SYSTEM
schtasks /create /tn "FreeITSM Recurring Tasks" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\task_recurrence.php" /sc daily /st 01:00 /ru SYSTEM
schtasks /create /tn "FreeITSM Calendar Sync Pull" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\calendar_sync_pull.php" /sc minute /mo 5 /ru SYSTEM
schtasks /create /tn "FreeITSM Documents Maintenance" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\scripts\documents_maintenance.php --quiet" /sc minute /mo 5 /ru SYSTEM
schtasks /create /tn "FreeITSM Attachment Text" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\cron\attachment_extract.php" /sc minute /mo 5 /ru SYSTEM
schtasks /create /tn "FreeITSM People Import" /tr "C:\wamp64\bin\php\php8.4.0\php.exe C:\wamp64\www\freeitsm-app\scripts\directory_sync.php --all --quiet" /sc daily /st 02:00 /ru SYSTEM
Things that catch people out on Windows
- If either path contains a space, the command above will fail. Put the whole thing in a
.batfile and point the task at that instead โ far easier than fightingschtasksquoting. /ru SYSTEMtasks are invisible to a normal user. Task Scheduler run without elevation will not list them, and neither will PowerShell'sGet-ScheduledTask. Open Task Scheduler as administrator to see them. A task you cannot see is not necessarily a task that does not exist.Last Run Resultof0x41303means "has not run yet" โ normal for a task you have just created. It should become0x0after its first run.- Check the task is Enabled, not merely present. A disabled task sits in the list looking perfectly healthy.
Linux (cron)
*/5 * * * * /usr/bin/php /var/www/freeitsm-app/cron/integration_poll.php >/dev/null 2>&1
*/5 * * * * /usr/bin/php /var/www/freeitsm-app/cron/sla_breach_check.php >/dev/null 2>&1
* * * * * /usr/bin/php /var/www/freeitsm-app/cron/webhook_deliveries.php >/dev/null 2>&1
*/5 * * * * /usr/bin/php /var/www/freeitsm-app/cron/workflow_scheduled.php >/dev/null 2>&1
0 1 * * * /usr/bin/php /var/www/freeitsm-app/cron/task_recurrence.php >/dev/null 2>&1
*/5 * * * * /usr/bin/php /var/www/freeitsm-app/cron/calendar_sync_pull.php >/dev/null 2>&1
*/5 * * * * /usr/bin/php /var/www/freeitsm-app/cron/attachment_extract.php >/dev/null 2>&1
*/5 * * * * /usr/bin/php /var/www/freeitsm-app/scripts/documents_maintenance.php --quiet >/dev/null 2>&1
0 2 * * * /usr/bin/php /var/www/freeitsm-app/scripts/directory_sync.php --all --quiet >/dev/null 2>&1
Drop the >/dev/null while you are testing, so cron emails you the output.
Running one by hand
Useful for testing, or before you have set the schedule up. From the application folder:
php cron/integration_poll.php
Each job prints what it did. The tracker poll, for example:
Jira checked 1, changed 0
comments: 1 seen, 1 imported
Checking they are working
The most reliable test is not "does the task exist" but "did something happen that only the job could have caused".
- Tracker poll โ change an issue's status in Jira, wait for two intervals, and see whether the pill on the linked ticket follows.
- Webhooks โ fire a workflow that sends one, then check the delivery queue empties.
- SLA โ the notification arrives, or it does not.
- Documents โ attach a file to anything, then search for a word that is only inside it. Before the job has run the file is found by its name only; afterwards, by its contents.
- Recurring tasks โ set a task to repeat on a fixed schedule with a date that has already passed, run the job by hand, and the next occurrence should appear. Running it twice must not produce two: creating an occurrence is idempotent on the series and the date. To check the start-date rule, give the task a start date a week before its due date and a repeat due a week from now โ it should be created straight away, dated in the future.
๐ก Each job refuses to run more often than a minimum interval, and each connection has its own interval too. So running a job twice in quick succession may print "No connections due" or "Rate limited". That is the job protecting itself, not a fault โ wait and run it again.
What is not a scheduled task
Worth knowing, so you do not go looking for a job that does not exist โ or create one that should not.
- Incoming email. Mailboxes are checked by the browser while an analyst has the ticket list open, not by a scheduled job. Mail therefore arrives when somebody is working, which is usually what you want, but it does mean nothing is collected overnight with every browser closed.
- Snoozed tickets waking up. There is no job. A snoozed ticket reappears because the snooze time has passed โ it is read from the clock whenever the folder is drawn.
- InTune synchronisation.
scripts/intune_worker.phpandintune_app_worker.phplook like cron jobs but are not. The application starts them itself when you run a sync. Do not schedule them.
See also: Installation ยท Issue trackers (Jira) ยท Workflows ยท Webhooks