Skip to content

fix: don't poison cached sync status on transient DB pool contention#772

Draft
Sotatek-HenryDo wants to merge 1 commit into
developfrom
fix/sync-status-refresh-resilience
Draft

fix: don't poison cached sync status on transient DB pool contention#772
Sotatek-HenryDo wants to merge 1 commit into
developfrom
fix/sync-status-refresh-resilience

Conversation

@Sotatek-HenryDo

Copy link
Copy Markdown
Collaborator

SyncStatusService.refreshSyncStatus() runs on a background scheduler thread that shares HikariCP's fixed-size pool with request-serving threads. Under heavy load, PostgreSQLIndexCreationMonitor.isCreatingIndexes() silently swallowed pool contention/timeout errors and returned a safe "not ready" default - which refreshSyncStatus() then wrote into the single cachedSyncStatus shared by every concurrent request, failing all of them for up to a full refresh interval even though the indexer was actually healthy.

Add IndexCreationMonitor.isCreatingIndexesOrThrow(), a variant that propagates the exception instead of swallowing it. refreshSyncStatus() now uses it (and catches around the whole refresh, including the latest-block lookup) so a transient failure just leaves the last known-good cached status in place instead of overwriting it with a false negative. isCreatingIndexes()'s existing swallow-and-default behavior is unchanged for its other caller (SyncStatusHealthIndicator).

SyncStatusService.refreshSyncStatus() runs on a background scheduler
thread that shares HikariCP's fixed-size pool with request-serving
threads. Under heavy load, PostgreSQLIndexCreationMonitor.isCreatingIndexes()
silently swallowed pool contention/timeout errors and returned a safe
"not ready" default - which refreshSyncStatus() then wrote into the
single cachedSyncStatus shared by every concurrent request, failing
all of them for up to a full refresh interval even though the indexer
was actually healthy.

Add IndexCreationMonitor.isCreatingIndexesOrThrow(), a variant that
propagates the exception instead of swallowing it. refreshSyncStatus()
now uses it (and catches around the whole refresh, including the
latest-block lookup) so a transient failure just leaves the last
known-good cached status in place instead of overwriting it with a
false negative. isCreatingIndexes()'s existing swallow-and-default
behavior is unchanged for its other caller (SyncStatusHealthIndicator).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Preprod Tests: PASSED

📊 View Detailed Test Report

🔗 Action Run #416

Tests run against preprod network with live blockchain data

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.

1 participant