Skip to content

Fix/reintroduced deadlock - #1104

Open
jona159 wants to merge 5 commits into
devfrom
fix/reintroduced-deadlock
Open

jona159 wants to merge 5 commits into
devfrom
fix/reintroduced-deadlock

Conversation

@jona159

@jona159 jona159 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Dependency upgrade
  • Bug fix (non-breaking change)
  • Breaking change
    • e.g. a fixed bug or new feature that may break something else
  • New feature
  • Code quality improvements
    • e.g. refactoring, documentation, tests, tooling, ...

Implementation

Checklist

  • I gave this pull request a meaningful title
  • My pull request is targeting the dev branch
  • I have added documentation to my code
  • I have deleted code that I have commented out

Additional Information

  • This PR closes #

@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability when saving measurements alongside location updates by preventing database lock conflicts.
    • Location records now update their geometry when an existing spatial match is found, keeping location data current.
    • Added consistent validation to prevent archived or unknown devices from receiving measurements.

Walkthrough

The change narrows location helper database contracts, updates conflicting location geometry, and moves location writes outside the measurement transaction. Device validation is shared between the pre-write phase and the measurement transaction.

Changes

Measurement persistence

Layer / File(s) Summary
Location helper database operations
app/lib/measurement-server-helper.ts
Location helpers now accept narrowed database interfaces. Conflicting location rows update their geometry. Device location inserts and filtering use the supplied database client.
Measurement save flow
app/db/models/measurement.server.ts
saveMeasurements validates the device and performs location writes before opening the measurement transaction. The transaction repeats validation through ensureDeviceCanReceiveMeasurements.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant saveMeasurements
  participant drizzleClient
  participant locationHelpers
  participant measurementTransaction
  saveMeasurements->>drizzleClient: validate device
  saveMeasurements->>locationHelpers: findOrCreateLocations and addLocationUpdates
  locationHelpers->>drizzleClient: write location data
  saveMeasurements->>measurementTransaction: open transaction
  measurementTransaction->>measurementTransaction: validate device
  measurementTransaction->>measurementTransaction: persist measurements
Loading

Merge Risk: 🟡 Moderate · up to 5183f

A rejected or failed measurement batch can leave device-location history behind, causing later measurements to use a location from an unaccepted batch. Preserve consistency without reintroducing the chunk-creation deadlock risk before merging.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description contains only an uncompleted template. It does not explain the deadlock fix, transaction changes, or location upsert changes. Add a concise implementation summary that explains the deadlock cause, the separation of location writes from the measurement transaction, and the conflict-update behavior. Complete the relevant checklist items.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title identifies the main change: fixing a reintroduced database deadlock. It is concise and related to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/reintroduced-deadlock

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 65.99% 2251 / 3411
🔵 Statements 64.47% 2323 / 3603
🔵 Functions 63.31% 435 / 687
🔵 Branches 50.61% 1076 / 2126
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
app/db/models/measurement.server.ts 58.82% 34.78% 71.42% 58.75% 35-160, 186, 187, 199-203, 295-297, 301, 354
app/lib/measurement-server-helper.ts 98.07% 94.73% 96.42% 97.91% 190-191
Generated in workflow #3060 for commit f6b4c23 by the Vitest Coverage Report Action

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 838a031e-b1d4-4e2c-936b-48fc4de1cd82

📥 Commits

Reviewing files that changed from the base of the PR and between 57accc7 and 5183f55.

📒 Files selected for processing (2)
  • app/db/models/measurement.server.ts
  • app/lib/measurement-server-helper.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

Comment thread app/db/models/measurement.server.ts
Comment on lines +125 to +128
.onConflictDoUpdate({
target: location.location,
set: { location: sql`excluded.location` },
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this deserves a comment on whats happening.
Essentially: We are not doing an OnConflictDoNothing because we wouldn't get a return value.
Alternatively the location column is set to the value proposed by the INSERT operation. This is essentially a no-op, because the location column is the cause for the conflict and thus the value in the database and the value given in this statement must be equal.

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.

2 participants