Skip to content

Conversation

@rroblf01
Copy link

@rroblf01 rroblf01 commented Nov 8, 2025

This pull request adds support for concurrent task processing in the database-backed worker by introducing multi-threading. The worker can now claim and process multiple tasks in parallel, controlled by a new --max-workers option. The changes also update the core query and locking logic to support batch task retrieval, and adjust related tests to reflect the new behavior.

Concurrency and worker configuration:

  • Added a --max-workers command-line option to the worker, allowing configuration of the maximum number of concurrent worker threads (default is 1, set by MAX_WORKERS) (django_tasks/backends/database/management/commands/db_worker.py, django_tasks/base.py). [1] [2] [3]
  • Updated the worker initialization and argument parsing to accept and use the max_workers parameter (django_tasks/backends/database/management/commands/db_worker.py). [1] [2] [3] [4]

Task claiming and processing logic:

  • Changed the worker loop to claim and process up to max_workers tasks concurrently using threads, instead of a single task at a time (django_tasks/backends/database/management/commands/db_worker.py). [1] [2]
  • Modified the get_locked method in the queryset to return a batch of locked tasks (as a queryset slice) instead of a single result, supporting batch locking (django_tasks/backends/database/models.py).

Testing updates:

  • Adjusted tests to accommodate the new batch locking and threading behavior, including changes to query counts and task locking logic (tests/tests/test_database_backend.py). [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]

These changes collectively enable the worker to process multiple tasks in parallel, improving throughput and efficiency for database-backed task queues.

@rroblf01
Copy link
Author

rroblf01 commented Nov 8, 2025

There are some things in this PR that need to be taken into account, such as that with my proposed changes, signal.SIGINT cannot terminate a running task, signal.SIGINT cannot terminate threads other than the main thread; as I have left it, the task would finish and then the worker would close.

Comment on lines 133 to 134
for thread in threads:
thread.join()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: I don't think this approach is ideal. If a worker process is set to run 5 threads, and receives 4 fast tasks and 1 long task, the worker will sit processing the long task and never pick up the extra 4 tasks is has capacity for.

@RealOrangeOne
Copy link
Owner

I'm not convinced this is necessarily a good idea. There are other systems which can be used above the worker process to handle running multiple, rather than adding that complexity to the worker process itself. Tools like supervisord, Kubernetes etc have done the work on how to manage multiple processes properly - that complexity probably shouldn't live in the worker.

@RealOrangeOne RealOrangeOne added the database-backend Issues relating to the database backend label Nov 14, 2025
…ra utilizar la función de validación valid_max_tasks.
@rroblf01
Copy link
Author

Hello @RealOrangeOne
I think it's important to be able to add threads directly to the command because otherwise, RAM consumption could skyrocket.

According to the tests I've run, each command consumes approximately 190MB of RAM. If I have to launch 5 workers to execute simple tasks (database queries, some HTTP requests, etc.), it could consume close to 1GB. However, if threads are integrated into the command, the consumption of the 5 workers would remain around the original 190MB.

I've modified the code so that no thread blocks another, and if there's a large task, it doesn't block any smaller tasks.

However, we've encountered two problems:

  • When using Ctrl+C, it doesn't stop immediately.
  • When moving database requests out of the main thread, the number of queries can't be counted in the tests.

@rroblf01
Copy link
Author

After using the changes I proposed in a work project, I realized that over time threads can become disabled, preventing code execution. Changing the threads to damon=True resolves this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

database-backend Issues relating to the database backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants