Background
Job Plugins are designed to generally run via cron, and so do not follow standard MVC patterns. However, since Plugins may be polymorphic, they may implement other functionality that does.
Entry Point Model
Job Plugins implement an Entry Point Model, defined in the Plugin's src/Lib/Jobs
directory, that implements a run()
function with the following signature:
public function run( \App\Model\Table\JobsTable $JobsTable, \App\Model\Table\JobsTable $JobHistoryRecordsTable, \App\Model\Entity\Job $job, array $parameters )
Note there is no defined return value. The entry point function is expected to update the Job record with status as it progresses. If the Job Plugin exits unexpectedly, the Job will automatically be placed in Failed
status.
Parameter Formats
The Entry Point Model must also implement a parameterFormat()
function that returns an array of parameters accepted by the plugin. This configuration is used to validate parameters passed to the Plugin when new Jobs are registered. Each entry in the array has a key of the parameter name and a value of an array with the following keys:
type
: One ofbool
,int
,select
, orstring
.required
: Boolean indicating whether or not this parameter is requiredchoices
: An array of permitted values for the parameter (whentype
isselect
)help
: Help text for the parameter
Database Access
Registry Job Command can run multiple Jobs in parallel, and accomplishes this by forking the current process. As a result, care must be taken when accessing database connections, or else a child process terminating may cause database connections to close for other processes. When launching a new Job (via a child process) Job Command will create a new database connection that should be used by the Job plugin. This is accomplished by setting the connection on the table to be queried.
This requirement may be removed in a future release. (CFM-253)
Example
// $plugin/src/config/plugin.json { "types": { "job": [ "WidgetJob" ] } } // $plugin/src/Lib/Jobs/WidgetJob.php use Cake\Datasource\ConnectionManager; use Cake\ORM\TableRegistry; class WidgetJob { public function parameterFormat(): array { return [ 'size' => [ 'type' => 'integer', 'required' => true, 'help' => "How big the widgets should be, in centimeters" ] ]; } public function run( \App\Model\Table\JobsTable $JobsTable, \App\Model\Table\JobsTable $JobHistoryRecordsTable, \App\Model\Entity\Job $job, array $parameters ) { // $JobsTable and $JobHistoryRecordsTable will already be set to use the correct connection, // but other tables need to be reconfigured to use the "plugin" connection $cxn = ConnectionManager::get('plugin') $Widgets = TableRegistry::getTableLocator->get('Widgets'); $Widgets->setConnection($cxn); $JobsTable->start(job: $job, summary: "Starting"); // Do some work, set the percent complete, record some history, etc $JobsTable->finish(job: $job, summary: "All done!"); } }