Welcome | Get started | Dive into Lino | Contribute | Reference | More
linod
: The Lino daemon¶
The lino.modlib.linod
plugin adds a framework for defining and handling
scheduled background tasks such as sending notifications or verifying data.
The "d" stands for "daemon", like in sshd, cupsd, systemd and other background processes on a Linux system.
It defines the linod
command, which is responsible for running the
background procedures defined by your
application. Background procedures are used for example for sending out
notification emails or running maintenance tasks such as checkdata
or
checksummaries
.
The linod
command also contains the log server, which is used
in production sites where multiple processes need to log to the
lino.log
.
When linod.use_channels
is True, this plugin uses channels to provide an ASGI interface.
- background task¶
A database row where the site manager specifies when to run a given background procedure on this site.
- background procedure¶
A concrete job defined by an application for running in background.
Usage¶
Other plugins can register a background task using the
dd.api.schedule_often()
or dd.api.schedule_daily()
decorators. For
example (taken from lino.modlib.checkdata
):
@dd.schedule_daily()
def checkdata(ar):
"""Run all data checkers."""
check_data(fix=False)
The code for the example above should be in one of your application's
models.py
modules.
>>> import lino
>>> lino.startup('lino_book.projects.noi1e.settings.demo')
>>> from lino.api.doctest import *
Background tasks¶
- class lino.modlib.linod.Procedure¶
Is basically a
Job
which contains a functionfunc
to run at default interval given byevery_unit
andevery_value
.The default interval can be overridden by
BackgroundTask
.- func¶
The function to run as a system task.
- Type:
Callable[[
BaseRequest
], None]
- start_datetime¶
The time at which this task should run first.
- Type:
datetime.datetime
- run(self, ar)¶
Calls the function stored in
func
passing ar as a positional argument.- Parameters:
ar -- an instance of
BaseRequest
- class lino.modlib.linod.Procedures¶
The choicelist of background procedures available in this application.
- class lino.modlib.linod.LogLevels¶
A choicelist of logging levels available in this application.
>>> rt.show(linod.LogLevels) ========== ========== =============== value text Numeric value ---------- ---------- --------------- DEBUG DEBUG 10 INFO INFO 20 WARNING WARNING 30 ERROR ERROR 40 CRITICAL CRITICAL 50 ========== ========== ===============
DEBUG
means to include detailed debug messages. You should not set this for a longer period on a production site because it bloats the log files.INFO
means to show informative messages.WARNING
is the recommended value for most tasks. Only warnings and error messages are logged.The levels
ERROR
andCRITICAL
(log only errors and critical messages) exist only for exceptional situations. You should probably not use them.
- class lino.modlib.linod.BackgroundTask¶
Django model used to represent a background task.
Overrides the recurrent rule of a
Procedure
.A subclass of
Sequenced
andRecurrenceSet
.- start_datetime¶
Tells at what time exactly this job started.
- Type:
datetime.datetime
- message¶
Stores information about the job, mostly logs.
- disabled¶
Tells whether the task should be ignored.
Lino sets this to True when the tasks fails and raises an exception. But it can also be checked by an end user in the web interface.
- run(self, ar, lgr=None) Job ¶
Performs a routine job.
Calls
self.procedure.run
.Cancels the rule in case of a failure.
Creates an instance of
Job
- Parameters:
ar -- An instance of
BaseRequest
lgr -- Logger obtained by calling logging.getLogger.
- Returns:
An instance of
Job
.
- class lino.modlib.linod.BackgroundTasks¶
The default actor for the
BackgroundTask
model.
- class lino.modlib.linod.RunJob¶
Manually run this task immediately.
Background procedures¶
>>> rt.show(linod.Procedures)
============================== ============================== ============================== ================================
value name text Suggested recurrency
------------------------------ ------------------------------ ------------------------------ --------------------------------
event_notification_scheduler event_notification_scheduler event_notification_scheduler every=300, every_unit=secondly
generate_calendar_entries generate_calendar_entries generate_calendar_entries every=1, every_unit=daily
checksummaries checksummaries checksummaries every=1, every_unit=daily
checkdata checkdata checkdata every=1, every_unit=daily
send_pending_emails_often send_pending_emails_often send_pending_emails_often every=10, every_unit=secondly
send_pending_emails_daily send_pending_emails_daily send_pending_emails_daily every=1, every_unit=daily
clear_seen_messages clear_seen_messages clear_seen_messages every=1, every_unit=daily
update_publisher_pages update_publisher_pages update_publisher_pages every=1, every_unit=daily
============================== ============================== ============================== ================================
While the procedures are in a choicelist (i.e. end users cannot edit them), the list of background tasks is configurable. The default situation is that every procedure has created one background task:
>>> rt.show(linod.BackgroundTasks)
===== ============================== =============== ========== =============
No. Background procedure Logging level Disabled Status
----- ------------------------------ --------------- ---------- -------------
1 event_notification_scheduler WARNING No Not started
2 generate_calendar_entries INFO No Not started
3 checksummaries INFO No Not started
4 checkdata INFO No Not started
5 send_pending_emails_often WARNING No Not started
6 send_pending_emails_daily INFO No Not started
7 clear_seen_messages INFO No Not started
8 update_publisher_pages INFO No Not started
===== ============================== =============== ========== =============
Simulating the daemon in a developer environment¶
To run the Lino daemon in a development environment run pm linod
in a
separate terminal.
Usage for developers¶
The lino.modlib.linod
plugin requires a running redis-server in the
background and also the django-channels, channels-redis Python packages to
be installed.
To install redis on a Debian-based Linux distribution, run the following command as root:
$ apt update
$ apt install redis
To install the required Python packages, run the following command after activating your Python environment:
$ pm install
>>> list(dd.plugins.linod.get_requirements(settings.SITE))
['channels', 'channels_redis', 'daphne']
Now you simply go to your project directory and invoke the admin command:
$ cd ~/projects/mysite
$ pm linod
This process will run as long as you don't kill it, e.g. until you hit Ctrl-C.
Don't read this¶
>>> bt = linod.BackgroundTask.objects.get(procedure=linod.Procedures.update_publisher_pages)
>>> bt.status
'Not started'
>>> ar = rt.login("robin")
>>> from asgiref.sync import async_to_sync
>>> async_to_sync(bt.start_task)(ar)
Start Background task #8 update_publisher_pages...
Update published pages...
72 pages have been updated.
>>> bt.status
'Scheduled to run at ... (... from now)'
Restore database state:
>>> bt.last_start_time = None
>>> bt.save()