fix(indexer): prevent overlapping poll executions#291
Open
drojas1316 wants to merge 1 commit into
Open
Conversation
Contributor
|
This PR's |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #256
Prevent overlapping indexer poll executions
What this changes
This PR replaces the indexer's fixed
setIntervalpolling schedule with a self-scheduling polling loop.The new polling flow:
setTimeoutonly after the previous poll succeeds or fails.POLL_MSdelay between polling executions.index.mjsis imported by tests.Why
The previous implementation used
setInterval, which could start another asynchronouspoll()call before the previous one had finished.This was especially likely during:
Concurrent polls could load the same cursor and process the same ledger range simultaneously, causing:
events.ndjson.export-csv.mjs.The new self-scheduling loop guarantees that only one poll can run at a time inside the process.
Checklist
cargo fmt --allandcargo clippy --all-targets -- -D warningspasscargo testpassesImplementation details
Self-scheduling polling loop
A new exported
runPollingLoop()function is responsible for polling and scheduling.Each iteration:
setTimeout.POLL_MSbefore starting the next poll.Because the timeout is created only after
poll()settles, two polling executions cannot overlap.Graceful shutdown
The previous interval identifier was replaced with a timeout identifier.
During shutdown, the indexer now calls:
This prevents a scheduled future poll from starting after shutdown has been requested.
Safe module imports
The indexer now checks whether
index.mjsis being executed directly before starting the polling loop.This allows the module to export
runPollingLoop()for testing without automatically starting the real indexer when the file is imported.Error recovery
Errors thrown by a poll are logged using the existing error-message behavior:
A failed poll does not terminate the scheduler. The next poll is still scheduled after the configured delay.
Tests
A regression test was added to verify the polling scheduler.
The test confirms that:
The test uses an injected scheduler and controlled promises, so it does not depend on arbitrary real-time delays.
Validation
The following command was run from the
indexerdirectory:npm testResult:
The diff was also checked with:
Result:
The polling path was reviewed to confirm that it no longer uses
setInterval.Files changed
indexer/index.mjsrunPollingLoop().indexer/index.test.mjsAcceptance criteria
POLL_MSdelay occurs between polling executions.Scope
This change addresses polling races within a single running indexer process.
It is separate from the restart, reorganization, and idempotency work discussed in: