Skip to content

Commit

Permalink
Added new plugin type - BackgroundTask
Browse files Browse the repository at this point in the history
  • Loading branch information
neonbunny committed Nov 19, 2024
1 parent 4f1361f commit 47a692c
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 8 deletions.
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,4 @@ Neo4j servers configured via the web UI will be used to:

## Reporting Plugins

It is possible to create your own reports for events and credentials by extended existing reporting plugin points.
Plugins are built with [django-plugins](https://pypi.org/project/django-plugins-bihealth/)
(Docs: https://django-plugins.readthedocs.io/en/latest/). Examples can be found within the various `*-reports` apps
included with the Stepping Stones project.

Place your own reporting plugins in a Django App which should then be extracted into the deployed Stepping Stones
Django Project and the new app included in the `INSTALLED_APPS` list within `stepping_stones\settings.py`.
It's possible to extend Stepping Stone's functionality via plugins. Additional docs are available [here](docs/plugins.md)
63 changes: 63 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Plugins

SteppingStones provides a number of extension points which can be used to add custom functionality to the project.
These are known as PluginPoints by the [plugin framework](https://pypi.org/project/django-plugins-bihealth/)
(Docs: https://django-plugins.readthedocs.io/en/latest/). Examples can be found within the various `*-reports` apps
included with the Stepping Stones project.

## Getting Started

To create a new plugin, first use the standard Django tools to create a new Django app:

```shell
python manage.py startapp my_plugin_name
```

Within the app add a `plugins.py` file and add one or more classes that extend the PluginPoints below.

Add the new Django App to the `INSTALLED_APPS` list in `stepping_stones\settings.py`

Run the Django plugins command to add the newly defined plugins to the database so Stepping Stones can find it:

```shell
python manage.py startapp my_plugin_name
```

## Plugin Points

### Reporting

#### EventReportingPluginPoint

A plugin point for a class which generates reports based on events in the main SteppingStones event database.

#### CredentialReportingPluginPoint

A plugin point for a class which generates reports based on credentials in the main Stepping Stones credential database.

### Background Tasks

#### BackgroundTaskPluginPoint

Used to start a background thread when SteppingStones starts. Task runs under the "ssbot" process / service.

##### Member Variables:

delay_seconds
: The number of seconds after SteppingStones starts to wait before running the initial background task. 30 (default)
means wait 30 seconds for SteppingStones to fully start before attempting to start the task.

repeat_seconds
: The number of seconds that should pass between invocations. 0 (default) means only run once.

replace_existing_tasks
: Boolean - True (default) means evict any previously scheduled tasks and only honour the delay/repeat values from now.

schedule_function
: A function pointer to the task to start. The function must:

* Be defined outside any classes (because the cls/self state can not be serialised)
* Be defined inside a file named `tasks.py` in the root of the plugin's Django application (to ensure the background task runner can find & import the function)
* Use the `background_task.background` decorator from [Django 4 Background Tasks](https://django4-background-tasks.readthedocs.io/en/latest/)


12 changes: 11 additions & 1 deletion event_tracker/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class EventTrackerConfig(AppConfig):
name = 'event_tracker'

def ready(self):
# Need to import these so that background_tasks lib can find the instrumented functions when it builds a task whitelist
# Need to import these so that background_tasks lib can find the decorated functions when it runs in its own
# process. The alternative is to declare the tasks in tasks.py.
from . import signals
from . import background_tasks

Expand All @@ -24,6 +25,7 @@ def ready(self):

from event_tracker.background_tasks import sync_disabled_users, sync_bh_owned, sync_pwnedpasswords
from background_task.models import Task
from event_tracker.plugins import BackgroundTaskPluginPoint

# Remove other sync_disabled_user tasks, there should only ever be one
Task.objects.filter(task_name="event_tracker.background_tasks.sync_disabled_users").delete()
Expand All @@ -34,3 +36,11 @@ def ready(self):

Task.objects.filter(task_name="event_tracker.background_tasks.sync_pwnedpasswords").delete()
sync_pwnedpasswords(schedule=timezone.now() + timedelta(seconds=120), repeat=180) # Run every 3 minutes, offset by 2 mins to allow sync_disabled_user to complete

for eventsourcebackgroundtaskplugin in BackgroundTaskPluginPoint.get_plugins():
if eventsourcebackgroundtaskplugin.is_active():
eventsourcebackgroundtaskplugin.schedule_function(schedule=eventsourcebackgroundtaskplugin.delay_seconds,
repeat=eventsourcebackgroundtaskplugin.repeat_seconds,
remove_existing_tasks=eventsourcebackgroundtaskplugin.replace_existing_tasks)


7 changes: 7 additions & 0 deletions event_tracker/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ def is_access_permitted(self, user):
return user.has_perms(perms)
else:
return False


class BackgroundTaskPluginPoint(PluginPoint):
delay_seconds = 30
repeat_seconds = 0
replace_existing_tasks = True
schedule_function = None

0 comments on commit 47a692c

Please sign in to comment.