Skip to content

[5] Remove old entity_history code and add history pruning - #338

Merged
JonoPrest merged 30 commits into
mainfrom
jp/history-cleanup
Nov 18, 2024
Merged

JonoPrest merged 30 commits into
mainfrom
jp/history-cleanup

Conversation

@JonoPrest

@JonoPrest JonoPrest commented Nov 15, 2024

Copy link
Copy Markdown
Collaborator
  • removes all old code related to unified entity_history table
  • adds new method of pruning entity history tables

let head = array->Js.Array2.slice(~start=0, ~end_=index)
let tail = array->Belt.Array.sliceToEnd(index + 1)
[...head, ...tail]
Belt.Array.concat(head, tail)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

No reason other than my tree sitter plugin wasn't parsing spreads and annoying me 😅

Comment on lines -125 to -126
let shouldSaveHistory =
RegisterHandlers.getConfig()->Config.shouldSaveHistory(~isInReorgThreshold)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Another place to remove the config lookup at the file level to ensure tests behave accordingly. "shouldSaveHistory" is now calculated and handed down.

Comment on lines +512 to +527
const tableName = makeHistoryTableName(entityName);
return sql`
WITH first_change AS (
SELECT
MIN(serial) AS first_change_serial
FROM
public.${sql(tableName)}
WHERE
${Utils.$$Array.interleave(
safeChainIdAndBlockNumberArray.map(
({ chainId, blockNumber }) =>
sql`(entity_history_chain_id = ${chainId} AND entity_history_block_number > ${blockNumber})`,
),
sql` OR `,
)}
),

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Since this doesn't relate to a given reorged chain, we need to check each chain for changes in their respective reorg thresholds and selected the earliest change out of those.

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.

Now safeChainIdAndBlockNumberArray started make sense :)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Any suggestions for a rename @DZakh?

Comment on lines +559 to +564
WHERE
-- Delete all entity history of entities that are not in the reorg threshold
eh.id NOT IN (SELECT id FROM items_in_reorg_threshold)
-- Delete all rows where id matches a row in previous_items but has a lower serial
OR
eh.serial < (SELECT serial FROM previous_items WHERE previous_items.id = eh.id);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The amazing advantage with this, is we only need to store history items for changes in the current reorg threshold + 1 historical change for each of those entities. Everything else can be cleared.

On new inserts, a defaulted zero value historical item is copied in from the current entity table so we can always keep the history table quite slim.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The only disadvantage is that this now has to be done as part of the batch transaction so we don't accidentally remove needed items due to async conditions. The main reason this query was running heavy before though is that there had to be at least one copy of every entity in the history table so it was quite large to do these expensive queries. Now it should be small based on changes within the reorg threshold of a chain.

Comment on lines +229 to +231
//History pruning needs to happen last in the transaction
//It deletes all unneeded history rows outside of the reorg threshold
pruneEntityHistory,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

History now gets pruned in the transaction after new history has been added and entities have been updated.

@JonoPrest
JonoPrest requested a review from DZakh November 18, 2024 10:22

@DZakh DZakh left a comment

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.

Nice ✅

~logger,
~loadLayer,
~isInReorgThreshold,
~shouldSaveHistory=config->Config.shouldSaveHistory(~isInReorgThreshold),

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.

Like that you started using `shouldSaveHistory

~inMemoryStore,
~isInReorgThreshold=false,
~config,
~safeChainIdAndBlockNumberArray=[], //No need to prune history for dynamic contract pre registration

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.

The naming is confusing. Maybe I'll understand what it means after reviewing further, but for now, I can only guess.

serializer: Utils.magic,
}),
])->S.setName("GqlDbCustomTypes.Float")
let schema = S.float->S.setName("GqlDbCustomTypes.Float")

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.

Nice

Comment on lines +512 to +527
const tableName = makeHistoryTableName(entityName);
return sql`
WITH first_change AS (
SELECT
MIN(serial) AS first_change_serial
FROM
public.${sql(tableName)}
WHERE
${Utils.$$Array.interleave(
safeChainIdAndBlockNumberArray.map(
({ chainId, blockNumber }) =>
sql`(entity_history_chain_id = ${chainId} AND entity_history_block_number > ${blockNumber})`,
),
sql` OR `,
)}
),

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.

Now safeChainIdAndBlockNumberArray started make sense :)

Comment thread codegenerator/cli/templates/static/codegen/src/eventFetching/ChainManager.res Outdated
//On the first time we enter the reorg threshold, copy all entities to entity history
//And set the isInReorgThreshold isInReorgThreshold state to true
dispatchAction(SetIsInReorgThreshold(true))
await DbFunctions.sql->DbFunctions.EntityHistory.copyAllEntitiesToEntityHistory

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.

🔥🔥🔥

Co-authored-by: Dmitry Zakharov <dzakh.dev@gmail.com>
@JonoPrest
JonoPrest force-pushed the jp/entity-history-diff branch from 64e94b6 to fe8a277 Compare November 18, 2024 16:15
Base automatically changed from jp/entity-history-diff to main November 18, 2024 16:26
@JonoPrest
JonoPrest merged commit 563737b into main Nov 18, 2024
@JonoPrest
JonoPrest deleted the jp/history-cleanup branch November 18, 2024 16:57
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