HOTFIX: Remove row-level locks from collector check-in path
Removed .with_for_update() from _replace_applications() which was acquiring row-level locks on every collector check-in (800/hour). These locks were holding during fingerprint comparison, blocking concurrent reads and causing severe performance degradation. The UNIQUE constraint on (assetid, app_fingerprint) already provides sufficient concurrency protection without explicit row locks. Impact: Eliminates 800 lock acquisitions per hour, unblocks reads during check-in processing. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1140,17 +1140,13 @@ class EndpointsPlugin(BasePlugin):
|
||||
|
||||
incoming_fps = set(incoming.keys())
|
||||
|
||||
# SAFETY: Row-level locking to prevent concurrent update races.
|
||||
# MySQL uses FOR UPDATE on the SELECT below (line 1157).
|
||||
# PostgreSQL would use pg_advisory_xact_lock here, but MySQL achieves
|
||||
# the same result via row-level locks + UNIQUE constraint on fingerprint.
|
||||
|
||||
# SAFETY: Memory limit check - prevent loading massive inventories
|
||||
# Query exactly MAX rows, then check if more exist (off-by-one fix)
|
||||
# Concurrency protection: UNIQUE constraint on (assetid, app_fingerprint)
|
||||
# handles race conditions without explicit row locks
|
||||
current_apps = (EndpointApplication.query
|
||||
.filter_by(assetid=assetid)
|
||||
.limit(MAX_APPS_PER_ENDPOINT)
|
||||
.with_for_update() # SAFETY: Row-level locking prevents concurrent races
|
||||
.all())
|
||||
|
||||
if len(current_apps) >= MAX_APPS_PER_ENDPOINT:
|
||||
|
||||
Reference in New Issue
Block a user