Skip to content

ref(relay): Reduce lock contention on Relay usage - #121987

Open
Dav1dde wants to merge 3 commits into
masterfrom
dav1d/relay-usage-locks
Open

ref(relay): Reduce lock contention on Relay usage#121987
Dav1dde wants to merge 3 commits into
masterfrom
dav1d/relay-usage-locks

Conversation

@Dav1dde

@Dav1dde Dav1dde commented Aug 13, 2026

Copy link
Copy Markdown
Member

On large request bursts this causes some contention on the RelayUsage model. Debounce the updates a bit.

I was also considering a select for update + skip locked, curious to hear opinions.

@Dav1dde
Dav1dde requested review from a team as code owners August 13, 2026 18:37
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Aug 13, 2026
cursor[bot]

This comment was marked as outdated.

@Dav1dde
Dav1dde force-pushed the dav1d/relay-usage-locks branch from 15989e6 to 4f17216 Compare August 13, 2026 18:39
Comment thread src/sentry/api/endpoints/relay/register_response.py Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fc4093d. Configure here.

@@ -101,9 +102,12 @@ def post(self, request: Request) -> Response:
except RelayUsage.DoesNotExist:
RelayUsage.objects.create(relay_id=relay_id, version=version, public_key=public_key)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Concurrent usage creates can 500

Medium Severity

Switching from get_or_create to a bare get plus create reopens a race on (relay_id, version). Concurrent first-time registrations can both miss the row, then the second create hits the unique constraint and returns 500 instead of taking the update path.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fc4093d. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, but that's not new. Can fix that in a separate PR

Comment thread src/sentry/api/endpoints/relay/register_response.py
Comment on lines +549 to +558

buffered_last_seen = mock_buffer_incr.call_args.kwargs["extra"]["last_seen"]
mock_buffer_incr.assert_called_once_with(
model=RelayUsage,
columns={},
filters={"id": rv1.id},
extra={"last_seen": buffered_last_seen, "public_key": str(key_pair[1])},
)
assert buffered_last_seen > after_second_relay
assert buffered_last_seen < after_re_register

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.

Nit: I think there's a way to force this to process so you can see that the update goes through. Maybe by using with self.tasks():. There are probably some examples in the code, it might be worthwhile to just verify that it works as expected

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

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants