Skip to content

Get next query improvements - #364

Merged
DZakh merged 11 commits into
mainfrom
dz/get-next-query
Nov 28, 2024
Merged

Get next query improvements#364
DZakh merged 11 commits into
mainfrom
dz/get-next-query

Conversation

@DZakh

@DZakh DZakh commented Nov 26, 2024

Copy link
Copy Markdown
Member
  • Make code execution more linear and logic more decoupled
  • Move waiting for the new block outside of the chain workers
  • Don't wait for the new block when there are partitions we still can query
  • Remove current height from the endBlock for HyperSync/HyperFuel queries
  • Added deduplication for new block polling

This may improve latency a little bit.

Comment on lines +17 to +26
let rec getKnownBlockWithBackoff = async (~provider, ~blockNumber, ~backoffMsOnFailure) =>
switch await getKnownBlock(provider, blockNumber) {
| exception err =>
Logging.warn({
"err": err,
"msg": `Issue while running fetching batch of events from the RPC. Will wait ${backoffMsOnFailure->Belt.Int.toString}ms and try again.`,
"type": "EXPONENTIAL_BACKOFF",
})
await Time.resolvePromiseAfterDelay(~delayMilliseconds=backoffMsOnFailure)
await getUnwrappedBlockWithBackoff(
await getKnownBlockWithBackoff(

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.

Changed the naming a little bit

Comment on lines +362 to +363
let getNextQueries = (self: t, ~maxPerChainQueueSize) => {
self.fetchState->PartitionedFetchState.getNextQueries(

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.

This doesn't interact with currentBlockHeight anymore. I think it made things easier.

Comment on lines -595 to -609
exception FromBlockIsHigherThanToBlock(int, int) //from and to block respectively

let isGreaterThanOpt: (int, option<int>) => bool = (a: int, b: option<int>) => {
switch b {
| Some(b) => a > b
| None => false
}
}

let rec getEndBlock = (self: register) => {
switch self.registerType {
| RootRegister({endBlock}) => endBlock
| DynamicContractRegister({nextRegister}) => nextRegister->getEndBlock
}
}

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.

Not needed anymore

type nextQueryOrWaitForBlock =
type nextQueryOrDone =
| NextQuery(nextQuery)
| WaitForNewBlock

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.

Moved all the interactions with global state to the global state module. Here we simply prepare a query and don't care how it'll be executed.

Comment on lines -628 to -635
/**
Gets the next query either with a to block of the current height if it is the root node.
Or with a toBlock of the nextRegistered latestBlockNumber to catch up and merge with the next regisetered.

Errors if nextRegistered dynamic contract has a lower latestFetchedBlock than the current as this would be
an invalid state.
*/
let getNextQuery = (self: t, ~currentBlockHeight, ~partitionId) => {

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.

Splitted it into two functions for reading simplicity

Comment on lines +92 to +95
toBlockExclusive: ?switch toBlockInclusive {
| Some(toBlockInclusive) => Some(toBlockInclusive + 1)
| None => None
},

@DZakh DZakh Nov 26, 2024

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.

I tried to compare the latest envio version with this one. Looked at TUI of the Fuel testnet indexer. I didn't really notice any difference, but I think it'll be more noticeable when HyperSync/network is lagging and takes more time to respond.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not related but maybe it would be worth firing that hook on a throttler as well. Makes the TUI less jittery

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.

Probably firing the hook as we do and throttle the render itself.

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.

Sounds like a good idea

Comment thread codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res Outdated
Comment thread codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res Outdated
Comment on lines +856 to +860
switch toBlock {
| Some(toBlock) if toBlock < fromBlock =>
//This is an invalid case. We should never arrive at this match arm but it would be
//detrimental if it were the case.
FromBlockIsHigherThanToBlock({fromBlock, toBlock})->ErrorHandling.mkLogAndRaise(

@DZakh DZakh Nov 26, 2024

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.

Moved the validation here. Now I don't really see a reason for this 😅

switch self.stateUpdatedHook {
| Some(hook) => hook(nextState)
| None => ()
| Some(hook) if self.state !== nextState => hook(nextState)

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.

Trigger the hook only when there's a change

@DZakh
DZakh requested a review from JonoPrest November 26, 2024 11:50
@DZakh

DZakh commented Nov 26, 2024

Copy link
Copy Markdown
Member Author

@JonoPrest Assigned you for an early review. The most concerning part is the potential stop of the indexer #364 (comment) . Let's sync when you have time, if my explanation doesn't make sense.

Also, I've realised that my solution will cause triggering the new block polling multiple times, I'd like to fix it.

registerType,
latestFetchedBlock: {
blockTimestamp: 0,
// Here's a bug that startBlock: 1 won't work

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ah I see, maybe we just allow a negative number here

let includesWaitForNewBlock = ref(false)
let getNextQueries = (self: t, ~maxPerChainQueueSize, ~partitionsCurrentlyFetching) => {
let nextQueries = []
let updatedPartitions = Js.Dict.empty()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't really see the purpose of returning this dict? Why not return the fully updated PartitionedFetchState?

@DZakh DZakh Nov 28, 2024

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.

No particular reason, but it allows to skip the state update when there are no merges

Comment on lines +481 to +490
{
...state,
chainManager: {
...state.chainManager,
chainFetchers: state.chainManager.chainFetchers->ChainMap.update(chain, chainFetcher => {
...chainFetcher->updateChainFetcherCurrentBlockHeight(~currentBlockHeight),
isWaitingForNewBlock: false,
}),
},
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks like this can use the updateChainFetcher helper like above. In fact looks like these two actions could be combined to pass "isWaitingForNewBlock" and just set that value.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nvmnd, see it includes current blockheight 👍🏼 but can still use the helper fn

…balStateManager.res

Co-authored-by: Jono Prest <65739024+JonoPrest@users.noreply.github.com>

@JonoPrest JonoPrest left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Great I like the changes!

…hainWorkers/ChainWorker.res

Co-authored-by: Jono Prest <65739024+JonoPrest@users.noreply.github.com>
@DZakh
DZakh enabled auto-merge (squash) November 28, 2024 11:06
@DZakh
DZakh merged commit b972e60 into main Nov 28, 2024
@DZakh
DZakh deleted the dz/get-next-query branch November 28, 2024 11:11
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