Repository navigation
feat(server): bulk event delete endpoint - #781
TimeToBuildBob wants to merge 5 commits into
Conversation
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #781 +/- ##
===========================================
+ Coverage 70.81% 83.79% +12.98%
===========================================
Files 51 82 +31
Lines 2916 10757 +7841
===========================================
+ Hits 2065 9014 +6949
- Misses 851 1743 +892 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Addressed the four P1 findings from Greptile in 559558b:
All 23 existing server tests still pass. |
|
@greptileai review |
🤖 AI code reviewAdds a bulk-delete endpoint POST /api/0/buckets/<bucket_id>/events/delete taking a JSON body {"ids": [...]}, returning u64 count of deleted events, with an upper bound on the number of ids, deduplication, query-cache invalidation, and a corresponding async client method AwClient::delete_events. Routes are registered in endpoints/mod.rs and an integration test covers success, empty, unknown bucket, and oversized cases. Safe to merge — no P0/P1 findingsConfidence 5/5 ✅ No findings. The diff looks correct to me on this pass. Files changed (4) — the diff as I read it
Previous review passes
Reviewed Maintainer commands
|
|
|
Addressed the Greptile re-review (second pass on 559558b): Fixed in 559558b (confirmed):
Partially addressed:
Known limitations accepted for maintainer review:
The Greptile score remains 3/5 after the second round. The two remaining findings are genuine but would require deeper datastore API changes or locking model rework. Leaving for maintainer review. |
|
@greptileai review |
|
CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click. This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted. |
|
Third round on this PR — fixed the root cause both reviewers had flagged, rather than deferring it. Fixed in 41c8d08: the write lock is now acquired before the
This does move the per-ID reads back inside the lock (Greptile's earlier "large deletes block event writes" note). Correctness wins here — range collection is part of the read-modify-invalidate sequence and cannot be made cache-correct outside it. Bulk delete is a client-driven cleanup path, not a hot path, and the datastore worker already serialises its operations; batching the O(n) lookups into a single datastore request is a reasonable follow-up to shorten the lock-held duration. Verified: Cross-repo, so no self-merge — leaving this for maintainer review. |
Convergence — ready for maintainer reviewReviewed at head Fixed in the branch (real findings):
Dispositioned with reasons (threads replied + resolved, not left open):
Status: CI green (ubuntu / macOS / windows / clippy / format / Android / coverage); Greptile 5/5 at Bob has pull-only access to this repo, so the merge is a maintainer click. |
…lete
Accepts {"ids": [...]}, ignores unknown/duplicate ids, returns the number
deleted, and invalidates the query cache for the removed ranges. Adds
AwClient::delete_events. Refs ActivityWatch#60.
Git-Session-Id: 606d
1. Unknown bucket: validate bucket existence before the ID loop so an empty-ids request to an unknown bucket returns 404, not 0. 2. Swallowed errors: only ignore NoSuchEvent; propagate all other DatastoreError variants instead of silently returning 0. 3. Lock hold time: acquire the write lock only for the delete and cache invalidation, not for the preceding per-ID lookup loop. 4. Stale cache: invalidate query-cache ranges on delete failure too, in case the datastore worker committed some deletes before the error. Git-Session-Id: 5c19562f-47b7-55a8-806d-20e6147ca7f5
The bulk-delete handler collected event ranges before acquiring the write lock, so a concurrent insert/heartbeat could replace an event with one of the same id at a different range. The delete then removed the new event while only the stale range was invalidated, leaving a stale query-cache entry, and the returned count could include ids another request had already deleted. Acquire the lock before the collection loop and hold it through the delete and invalidation, matching bucket_events_create and bucket_events_delete_by_id. Git-Session-Id: fbe0cb40-6e2d-5288-822a-f02915f7d321
…scan Git-Session-Id: 6072b952-8db1-5460-a333-10ccdda0143e
Git-Session-Id: 6072b952-8db1-5460-a333-10ccdda0143e
49174d0 to
030493b
Compare
|
Rebased onto master (fcc1ede) to clear the conflict. Dropped Local check on the new head 030493b: |
Adds
POST /api/0/buckets/<bucket_id>/events/deletewith body{"ids": [1, 2, 3]}, plusAwClient::delete_events. Refs #60 and ActivityWatch/aw-server#55.Datastore::delete_events_by_id(already list-based; the datastore worker runs it as one operation) and invalidates the query cache for the removed events' ranges, like the single-delete route.DELETE .../events/<id>route. The issue suggests replacing it, but removing it breaks clients, so I left that call to maintainers.secure_delete(separate concerns from the issue discussion), and the Python aw-server parity port (follow-up).Verified: new
test_bulk_delete_events(mixed known/unknown/duplicate ids, empty list, unknown bucket) passes;cargo fmtclean. The local clippy hook fails only on the pre-existingaw-query/src/lib.rsduplicate-attribute error (fixed by #771); I committed withSKIP=cargo-clippyfor that hook alone.