CRON (aka time-based job scheduler) - HL Vanilla Community
<main> <article class="userContent"> <div class="embedExternal embedImage display-large float-none"> <div class="embedExternal-content"> <a class="embedImage-link" href="https://us.v-cdn.net/6030677/uploads/UC1W4O2V0AOT/microsoftteams-image-288-29.png" rel="nofollow noreferrer noopener ugc" target="_blank"> <img class="embedImage-img" src="https://us.v-cdn.net/6030677/uploads/UC1W4O2V0AOT/microsoftteams-image-288-29.png" alt="MicrosoftTeams-image (8).png" height="108" width="1356" loading="lazy" data-display-size="large" data-float="none"></img></a> </div> </div> <h3 data-id="what-is-a-cron-job">What is a cron job?</h3><p>A cron job is just a plain old job that will run at specific intervals of time based on a cron expression.</p><h3 data-id="how-and-where-to-schedule-a-cron-job">How and where to schedule a cron job?</h3><p>Cron jobs need to be scheduled on the bootstrap process and the <code class="code codeInline" spellcheck="false" tabindex="0">Scheduler</code> will trigger those when the <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code> endpoint is hit.</p><p>What will differentiate a regular job from a cron job is the job descriptor used to schedule the job itself.</p><h3 data-id="what-is-a-job-descriptor">What is a job descriptor?</h3><p>A <code class="code codeInline" spellcheck="false" tabindex="0">JobDescriptorInterface</code> is used to describe a job. A Job descriptor doesn't change the job in any form, it just helps the <code class="code codeInline" spellcheck="false" tabindex="0">Scheduler</code> to decide if the job needs to be run or not.</p><p>There are two main implementations of the interface <code class="code codeInline" spellcheck="false" tabindex="0">NormalJobDescriptor</code> and <code class="code codeInline" spellcheck="false" tabindex="0">CronJobDescriptor</code>.</p><p>A <code class="code codeInline" spellcheck="false" tabindex="0">CronJobDescriptor</code> will take a Job and a cron expression as a parameter. A cron expression is a simple string that tells when you want to run the job. For example <code class="code codeInline" spellcheck="false" tabindex="0">*/5 * * * *</code> will run the job at every 5th minute.</p><p>Take a look at <a href="https://crontab.guru/" rel="nofollow noreferrer ugc">https://crontab.guru/</a> if you are not fully into cron expressions.</p><p>By design, the minimum granularity of a cron expression is 1 minute.</p><h5 data-id="example">Example</h5><pre class="code codeBlock" spellcheck="false" tabindex="0">$scheduler = $containter->get(SchedulerInterface::class); // The job is meant to run every minute $scheduler->addJobDescriptor(new CronJobDescriptor(EchoJob::class, '* * * * *')); </pre><h3 data-id="scheduler's-execution-type">Scheduler's execution type</h3><p>The Scheduler's <code class="code codeInline" spellcheck="false" tabindex="0">JobExecutionType</code> will hint to the <code class="code codeInline" spellcheck="false" tabindex="0">Scheduler</code> about what kind of job it should dispatch.</p><p>The default mode, <code class="code codeInline" spellcheck="false" tabindex="0">JobExecutionType::normal()</code>, will be used in a regular request. <code class="code codeInline" spellcheck="false" tabindex="0">JobExecutionType::cron()</code> will be used to hint the Scheduler about running cron jobs.</p><h3 data-id="post-apiv2schedulercron">POST /api/v2/scheduler/cron</h3><p>The most straightforward way to trigger a cron execution is using the <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code> endpoint.</p><p><code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code> will do the following:</p><ul><li>It will set the Scheduler on <code class="code codeInline" spellcheck="false" tabindex="0">JobExecutionType::cron()</code></li><li>It will fire the event <code class="code codeInline" spellcheck="false" tabindex="0">CRON_TRIGGER_EVENT</code></li><li>It will fire the Scheduler's dispatcher at the end of request (as any other request)</li></ul><p>Why firing <code class="code codeInline" spellcheck="false" tabindex="0">CRON_TRIGGER_EVENT</code>?</p><p>The event allows any listener to add cron jobs into the <code class="code codeInline" spellcheck="false" tabindex="0">Scheduler</code>. Hooking into the event is NOT needed, it just gives you an additional opportunity to do so.</p><p>The use case in mind for this will be the following: To schedule a cron-job you need to run an intensive process (querying the database, contacting a remote service, etc), it would make no sense to do the calculation for every request, it will be better to do it just when you are sure a cron execution is running. The event helps you to be sure of that.</p><p>Because cron jobs will <em>mainly</em> be triggered when <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code> is hit, there are some special situations to consider.</p><p>The scheduler will run cron jobs at the defined minimum timespan (default of 1 minute). If you hit the endpoint more than once during the timespan, the jobs triggered on the second or following request will be abandoned.</p><p>For a cron job to be abandoned is the same as no hitting the endpoint. Why? Because the <code class="code codeInline" spellcheck="false" tabindex="0">Scheduler</code> will take the last time it ran cron jobs to establish is any given cron job should run or not (based on the descriptor's schedule). As a consequence of this:</p><ul><li>No cron job will be missed in case the endpoint is not hit. They will run the next time.</li><li>No cron job will run more than once in any given interval between two endpoint calls. For example: <code class="code codeInline" spellcheck="false" tabindex="0">*/10 * * * *</code>, should run every 10 minutes, however, if you are hitting the endpoint once an hour, the job will run one time (not 6)</li><li>If no information is available to know when the <code class="code codeInline" spellcheck="false" tabindex="0">Scheduler</code> ran cron jobs for the last time, one day in the past will be used as default.</li><li>Vanilla Cloud will hit <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code> around every 5 minutes.</li></ul><h2 data-id="vanilla-cloud-feature-flag">Vanilla Cloud - Feature flag</h2><p>To enable the cron functionality on Vanilla Cloud, you need to set the site configuration <code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.Token</code></p><h3 data-id="configurations">Configurations</h3><p><code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.Token</code>: Mandatory. Authentication token for accessing <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code> </p><p><code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.CronMinimumTimeSpan</code>: Optional. The minimum amount of time between two consecutive cron triggers. Default <code class="code codeInline" spellcheck="false" tabindex="0">60</code> seconds.</p><h3 data-id="troubleshooting">Troubleshooting</h3><p>I am working locally and my cron job is not running. What should I check?</p><ul><li>Did you set <code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.Token</code>?</li><li>Did you hit the <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code>endpoint?</li><li>Did you pass your <code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.Token</code> into the <code class="code codeInline" spellcheck="false" tabindex="0">Authorization</code> header when you called <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code>?</li><li>Did you wait for <code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.CronMinimumTimeSpan</code> between calls to the endpoint? Tip: Set <code class="code codeInline" spellcheck="false" tabindex="0">Garden.Scheduler.CronMinimumTimeSpan</code> to a very low value</li><li>Was your job scheduled when you hit <code class="code codeInline" spellcheck="false" tabindex="0">POST /api/v2/scheduler/cron</code>?</li></ul><p><br></p> </article> </main>