BackgroundTask

Contains functions for running tasks in the background.

remapp.tools.background.get_current_task()
Returns

The associated BackgroundTask object when called in a task. If this is not executed in a background Task None will be returned.

remapp.tools.background.get_or_generate_task_uuid()
Returns

If called from within a task the task id, else a generated uuid

remapp.tools.background.record_task_error_exit(error_msg)

Small helper that checks if we are in a task and assuming we are records error_msg as well as setting the completed_successfully to false and completed to True. Note that get_current_task will return None after a call to this.

remapp.tools.background.record_task_info(info_msg)

Small helper that checks if we are in a task and assuming we are records info_msg as info.

Tries to find the related DicomQRRspStudy object given a study instance uid and if this is running in a task will record it to the query object. This is used to later find the import tasks that were run as part of a query. Since this actually just takes the latest query if the user runs imports manually via script it may in principle wrongly associate.

remapp.tools.background.run_as_task(func, task_type, num_proc, num_of_task_type, taskuuid, *args, **kwargs)

Runs func as a task. (Which means it runs normally, but a BackgroundTask object is created and hence the execution as well as occurred errors are documented and visible to the user).

As a note: This is used as a helper for run_in_background. However, in principle it could also be used to run any function in sequential for which we would like to document that it was executed. (Has some not so nice parts, especially that user can terminate a bunch of sequentially running tasks)

Note that waiting here if it is ok to start is actually quite ugly, since running a lot of processes with conditions will use a lot of RAM without any use. This however is the simplest possible fix for making the run_in_background_with_limits non-blocking, which is a requirement for the docker import. A nice update would be to either have 1 process managing the execution of the other processes, or at least do this based on signalling from the exiting processes instead of polling.

This can sometimes lead to errors with sqlite, see (tasks keep hanging then) https://stackoverflow.com/questions/28958580/django-sqlite-database-is-locked

Parameters
  • func – The function to run

  • task_type – A string documenting what kind of task this is

  • num_proc – The maximum number of processes that should be executing

  • num_of_task_type – The maximum number of processes for multiple tasks type which are allowed to run at the same time

  • taskuuid – An uuid which will be used as uuid of the BackgroundTask object. If None, will generate one itself

Args

Args to func

Kwargs

Args to func

Returns

The created BackgroundTask object

remapp.tools.background.run_in_background(func, task_type, *args, **kwargs)

Syntactic sugar around run_in_background_with_limits.

Arguments correspond to run_in_background_with_limits. Will always run the passed function as fast as possible. This function should always be used for functions triggered from the webinterface.

remapp.tools.background.run_in_background_with_limits(func, task_type, num_proc, num_of_task_type, *args, **kwargs)

Runs fun as background Process.

This method will create a BackgroundTask object, which can be obtained via get_current_task() inside the calling process. This function will not return until the BackgroundTask object exists in the database. Potentially it may only return after the process has already exited. Note that BackgroundTask objects will not be deleted onto completion - instead the complete flag will be set to True. This function cannot be used with Django Tests, unless they use TransactionTestCase instead of TestCase (which is far slower, so use with caution). num_proc and num_of_task_type can be used to give conditions on the start.

Parameters
  • func – The function to run. Note that you should set the status of the task yourself and mark as completed when exiting yourself e.g. via sys.exit(). Assuming the function returns normally on success or returns with an exception on error, the status of the BackgroundTask object will be set correctly.

  • task_type – One of the strings declared in BackgroundTask.task_type. Indicates which kind of background process this is supposed to be. (E.g. move, query, …)

  • num_proc – Will wait with execution until there are less than num_proc active tasks. If num_proc == 0 will run directly

  • num_of_task_type – A dictionary from str to int, where key should be some used task_type. Will wait until there are less active tasks of task_type than specified in the value of the dict for that key.

  • args – Positional arguments. Passed to func.

  • kwargs – Keywords arguments. Passed to func.

Returns

The BackgroundTask object.

remapp.tools.background.terminate_background(task: BackgroundTask)

Terminate a background task by force. Sets complete=True on the task object.

remapp.tools.background.wait_task(task: BackgroundTask)

Wait until the task has completed