Skip to content

Commit

Permalink
Merge pull request #2048 from timopollmeier/change-autodelete-locking
Browse files Browse the repository at this point in the history
Change: Lock table for each auto-deleted report individually
  • Loading branch information
jhelmold authored Jul 21, 2023
2 parents e0b092d + bbebfae commit 94f9c6b
Showing 1 changed file with 51 additions and 25 deletions.
76 changes: 51 additions & 25 deletions src/manage_sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -18917,15 +18917,7 @@ auto_delete_reports ()

g_debug ("%s", __func__);

sql_begin_immediate ();

/* As in delete_report, this prevents other processes from getting the
* report ID. */
if (sql_int ("SELECT try_exclusive_lock('reports');") == 0)
{
sql_rollback ();
return;
}
GArray *reports_to_delete = g_array_new (TRUE, TRUE, sizeof(report_t));

init_iterator (&tasks,
"SELECT id, name,"
Expand Down Expand Up @@ -18970,31 +18962,65 @@ auto_delete_reports ()
keep);
while (next (&reports))
{
int ret;
report_t report;

report = iterator_int64 (&reports, 0);
assert (report);

g_debug ("%s: delete %llu", __func__, report);
ret = delete_report_internal (report);
if (ret == 2)
{
/* Report is in use. */
g_debug ("%s: %llu is in use", __func__, report);
continue;
}
if (ret)
{
g_warning ("%s: failed to delete %llu (%i)",
__func__, report, ret);
sql_rollback ();
}
g_debug ("%s: %llu to be deleted", __func__, report);

g_array_append_val (reports_to_delete, report);
}
cleanup_iterator (&reports);
}
cleanup_iterator (&tasks);
sql_commit ();

for (int i = 0; i < reports_to_delete->len; i++)
{
int ret;
report_t report = g_array_index (reports_to_delete, report_t, i);

sql_begin_immediate ();

/* As in delete_report, this prevents other processes from getting the
* report ID. */
if (sql_int ("SELECT try_exclusive_lock('reports');") == 0)
{
g_debug ("%s: could not acquire lock on reports table", __func__);
sql_rollback ();
g_array_free (reports_to_delete, TRUE);
return;
}

/* Check if report still exists in case another process has deleted it
* in the meantime. */
if (sql_int ("SELECT count(*) FROM reports WHERE id = %llu",
report) == 0)
{
g_debug ("%s: %llu no longer exists", __func__, report);
sql_rollback ();
continue;
}

g_debug ("%s: deleting report %llu", __func__, report);
ret = delete_report_internal (report);
if (ret == 2)
{
/* Report is in use. */
g_debug ("%s: %llu is in use", __func__, report);
sql_rollback ();
continue;
}
if (ret)
{
g_warning ("%s: failed to delete %llu (%i)",
__func__, report, ret);
sql_rollback ();
continue;
}
sql_commit ();
}
g_array_free (reports_to_delete, TRUE);
}


Expand Down

0 comments on commit 94f9c6b

Please sign in to comment.