Skip to content

Conversation

@akshayutture-augment
Copy link

@akshayutture-augment akshayutture-augment commented Nov 14, 2025

Test 7


Replicated from ai-code-review-evaluation/grafana-cursor#7


Note

Refactors annotation cleanup to fetch and delete IDs in batches (avoiding MySQL deadlocks), updates integration tests with bulk inserts and large-batch scenarios, and runs the cleanup loop every minute.

  • Annotations cleanup:
    • Switch from subquery DELETEs to batched "fetch IDs then delete by IDs" to avoid deadlocks; shared helper functions fetchIDs, deleteByIDs, untilDoneOrCancelled, asAny.
    • Handle SQLite parameter limits when batch size exceeds 999; add detailed logging.
    • Apply the same batched approach to annotation_tag orphan cleanup.
  • Tests:
    • Convert cleanup tests to integration tests; generate data via InsertMulti, add annotation_tag rows, and parameterize AnnotationCleanupJobBatchSize.
    • Add case covering large batch sizes on SQLite (>= 3.32.0).
  • Cleanup service:
    • Increase periodic cleanup frequency from 10 minutes to 1 minute.

Written by Cursor Bugbot for commit 81c45bf. Configure here.

… deadlocks on MySQL (#80329)

* Split subquery when cleaning annotations

* update comment

* Raise batch size, now that we pay attention to it

* Iterate in batches

* Separate cancellable batch implementation to allow for multi-statement callbacks, add overload for single-statement use

* Use split-out utility in outer batching loop so it respects context cancellation

* guard against empty queries

* Use SQL parameters

* Use same approach for tags

* drop unused function

* Work around parameter limit on sqlite for large batches

* Bulk insert test data in DB

* Refactor test to customise test data creation

* Add test for catching SQLITE_MAX_VARIABLE_NUMBER limit

* Turn annotation cleanup test to integration tests

* lint

---------

Co-authored-by: Sofia Papagiannaki <[email protected]>
@akshayutture-augment
Copy link
Author

cursor review

placeholders := "?" + strings.Repeat(",?", len(ids)-1)
sql = fmt.Sprintf(`DELETE FROM %s WHERE id IN (%s)`, table, placeholders)
args = asAny(ids)
}
Copy link

Choose a reason for hiding this comment

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

Bug: SQLite Parameter Limit: The Check That Fails

The SQLite parameter limit check compares the configured AnnotationCleanupJobBatchSize instead of the actual number of IDs being deleted. When batch size is small but len(ids) exceeds 999 (SQLite's parameter limit), the code uses parameterized queries which will fail. The condition should check len(ids) > sqliteParameterLimit instead of r.cfg.AnnotationCleanupJobBatchSize > sqliteParameterLimit.

Fix in Cursor Fix in Web

r.log.Error("Tags to clean", "count", len(ids), "ids", ids, "cond", cond, "err", err)

x, y := r.deleteByIDs(ctx, "annotation_tag", ids)
r.log.Error("cleaned tags", "count", len(ids), "affected", x, "err", y)
Copy link

Choose a reason for hiding this comment

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

Bug: Misconfigured logging floods error channels.

Debug logging statements use Error() level instead of Debug() for normal operational information. Lines 534, 537, 554, 557, 576, and 579 log routine cleanup progress at ERROR level even when no error occurs, which creates false error alerts in logging systems and should be DEBUG or removed.

Fix in Cursor Fix in Web

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants