Skip to content

Commit

Permalink
Merge pull request #1097 from nextcloud/backport/1074/stable15
Browse files Browse the repository at this point in the history
[stable15] Improve background job documentation now that it is in OCP
  • Loading branch information
MorrisJobke authored Jan 2, 2019
2 parents cab8635 + 50ef48b commit 49a1354
Showing 1 changed file with 101 additions and 15 deletions.
116 changes: 101 additions & 15 deletions developer_manual/app/backgroundjobs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,122 @@ Background jobs (Cron)

.. sectionauthor:: Bernhard Posselt <dev@bernhard-posselt.com>

Background/cron jobs are usually registered in the :file:`appinfo/app.php` by using the **addRegularTask** method, the class and the method to run:
Often there is a need to run background jobs. For example there are Background
jobs in Nextcloud that send out the activity emails. Or expire the trashbin.

.. code-block:: php
Types of background jobs
------------------------
Nextcloud by default offers you two types of background jobs. The ``\OCP\BackgroundJob\QueuedJob``
and ```\OCP\BackgroundJob\TimedJob``.

<?php
\OCP\Backgroundjob::addRegularTask('\OCA\MyApp\Cron\SomeTask', 'run');
The ``QueuedJob`` is for one time jobs. This can for example be triggered by inserting
a job because an event happened. The ``TimedJob`` has a method ``setInterval`` where
you can set the time minimum time in seconds between the jobs (from the constructor).
This is useful in case you want to have a job that is run at most once a day for example.

Of course you can customize this all to your liking by just extending ``\OCP\BackgroundJob\Job``

The class for the above example would live in :file:`cron/sometask.php`. Try to keep the method as small as possible because its hard to test static methods. Simply reuse the app container and execute a service that was registered in it:
Writing a background job
------------------------

Writing a background job is rather straight forward. You write a class and extend
your job class of choice.

.. code-block:: php
<?php
namespace OCA\MyApp\Cron;
use \OCA\MyApp\AppInfo\Application;
use \OCA\MyApp\Service\SomeService;
use \OCP\BackgroundJob\TimedJob;
class SomeTask extends TimedJob {
class SomeTask {
private $myService;
public static function run() {
$app = new Application();
$container = $app->getContainer();
$container->query('SomeService')->run();
public function __construct(ITimeFactory $time, SomeService $service) {
parent::__construct($time);
$this->myService = $service;
// Run once an hour
parent::setInterval(3600);
}
public static function run($arguments) {
$this->myService->doCron($arguments['uid']);
}
}
Don't forget to configure the cron service on the server by executing::
As you can see our dependency injection also works just fine for background jobs.
The ITimeFactory always needs to be passed to the parent constructor. Since it is
required to be set.

In this case it is a background job that runs every hour. And we take the ``uid`` arguemnt
to pass on to the service to run the background job.

The ``run`` function is the main thing you need to implement and where all the
logic happens.

Registering a background job
----------------------------

Now that you have written your background job there is of course the small matter of
how to make sure the system actually runs your job. In order to do this your
job needs to be registered.

info.xml
^^^^^^^^

You can register your jobs in your info.xml by addning;

.. code-block:: xml
<background-jobs>
<job>OCA\MyApp\Cron\SomeTask</job>
</background-jobs>
This will on install/update of the application add the job ``OCA\MyApp\Cron\SomeTask``.
Of course in this case the arguments passed to your ``run`` function is just an empty
array.

sudo crontab -u http -e
Registering manually
^^^^^^^^^^^^^^^^^^^^

where **http** is your Web server user, and add::
In case you want more fine grained control about when a background job is inserted
and you want to pass arguments to it you need to manually register your background jobs.

You do this by using ``\OCP\BackgroundJob\IJobList``. There you can add a job or remove a job.

For example you could add or remove a certain job based on some controller:

.. code-block:: php
<?php
namespace OCA\MyApp\Controller;
use \OCA\MyApp\Cron\SomeTask;
use \OCP\AppFramework\Controller;
use \OCP\BackgroundJob\IJobList;
class SomeController extends Controller {
private $jobList
public function __construct(string $appName, IRequest $request, IJobList $jobList) {
parent::__construct($appName, $request);
$this->jobList = $jobList;
}
public function addJob(string $uid) {
$this->jobList->add(SomeTask::class, ['uid' => $uid]);
}
public function removeJob(string $uid) {
$this->jobList->remove(SomeTask::class, ['uid' => $uid]);
}
}
*/15 * * * * php -f /srv/http/nextcloud/cron.php
This provides more fine grained control and you can pass arguments to your background
jobs easily.

0 comments on commit 49a1354

Please sign in to comment.