-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(17/recurring-task-lock): Add timeout to auto unlock task
- Loading branch information
1 parent
f92adfd
commit 6e07161
Showing
6 changed files
with
228 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
task_processor/migrations/0012_add_locked_at_and_timeout.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Generated by Django 3.2.23 on 2025-01-06 04:51 | ||
|
||
from task_processor.migrations.helpers import PostgresOnlyRunSQL | ||
import datetime | ||
from django.db import migrations, models | ||
import os | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("task_processor", "0011_add_priority_to_get_tasks_to_process"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="recurringtask", | ||
name="locked_at", | ||
field=models.DateTimeField(blank=True, null=True), | ||
), | ||
migrations.AddField( | ||
model_name="recurringtask", | ||
name="timeout", | ||
field=models.DurationField(default=datetime.timedelta(minutes=30)), | ||
), | ||
migrations.AddField( | ||
model_name="task", | ||
name="timeout", | ||
field=models.DurationField(blank=True, null=True), | ||
), | ||
PostgresOnlyRunSQL.from_sql_file( | ||
os.path.join( | ||
os.path.dirname(__file__), | ||
"sql", | ||
"0012_get_recurringtasks_to_process.sql", | ||
), | ||
reverse_sql="DROP FUNCTION IF EXISTS get_recurringtasks_to_process", | ||
), | ||
] |
32 changes: 32 additions & 0 deletions
32
task_processor/migrations/sql/0012_get_recurringtasks_to_process.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
CREATE OR REPLACE FUNCTION get_recurringtasks_to_process(num_tasks integer) | ||
RETURNS SETOF task_processor_recurringtask AS $$ | ||
DECLARE | ||
row_to_return task_processor_recurringtask; | ||
BEGIN | ||
-- Select the tasks that needs to be processed | ||
FOR row_to_return IN | ||
SELECT * | ||
FROM task_processor_recurringtask | ||
WHERE is_locked = FALSE OR (locked_at IS NOT NULL AND locked_at < NOW() - timeout) | ||
ORDER BY id | ||
LIMIT num_tasks | ||
-- Select for update to ensure that no other workers can select these tasks while in this transaction block | ||
FOR UPDATE SKIP LOCKED | ||
LOOP | ||
-- Lock every selected task(by updating `is_locked` to true) | ||
UPDATE task_processor_recurringtask | ||
-- Lock this row by setting is_locked True, so that no other workers can select these tasks after this | ||
-- transaction is complete (but the tasks are still being executed by the current worker) | ||
SET is_locked = TRUE, locked_at = NOW() | ||
WHERE id = row_to_return.id; | ||
-- If we don't explicitly update the columns here, the client will receive a row | ||
-- that is locked but still shows `is_locked` as `False` and `locked_at` as `None`. | ||
row_to_return.is_locked := TRUE; | ||
row_to_return.locked_at := NOW(); | ||
RETURN NEXT row_to_return; | ||
END LOOP; | ||
|
||
RETURN; | ||
END; | ||
$$ LANGUAGE plpgsql | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.