Skip to content

Commit

Permalink
Implement cache for latest updated entities to be used in mapping code (
Browse files Browse the repository at this point in the history
#194)

* Load relations according to GQL query

* Implement cache for latest entities to used in mapping code

* Add metrics for cache hit and fix caching pruned entities

* Changes in codegen and graph-test-watcher

* Remove entity load counter reset to zero
  • Loading branch information
nikugogoi authored Oct 4, 2022
1 parent 6149690 commit 18861ea
Show file tree
Hide file tree
Showing 19 changed files with 695 additions and 246 deletions.
24 changes: 19 additions & 5 deletions packages/codegen/src/templates/indexer-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DeepPartial, FindConditions, FindManyOptions } from 'typeorm';
import JSONbig from 'json-bigint';
import { ethers } from 'ethers';
import _ from 'lodash';
import { SelectionNode } from 'graphql';

import { JsonFragment } from '@ethersproject/abi';
import { BaseProvider } from '@ethersproject/providers';
Expand Down Expand Up @@ -350,12 +351,16 @@ export class Indexer implements IPLDIndexerInterface {
return createStateCheckpoint(this, contractAddress, blockHash);
}

async processCanonicalBlock (blockHash: string): Promise<void> {
async processCanonicalBlock (blockHash: string, blockNumber: number): Promise<void> {
// Finalize staged diff blocks if any.
await this._baseIndexer.finalizeDiffStaged(blockHash);

// Call custom stateDiff hook.
await createStateDiff(this, blockHash);
{{#if (subgraphPath)}}

this._graphWatcher.pruneEntityCacheFrothyBlocks(blockHash, blockNumber);
{{/if}}
}

async processCheckpoint (blockHash: string): Promise<void> {
Expand Down Expand Up @@ -442,8 +447,13 @@ export class Indexer implements IPLDIndexerInterface {
}

{{#if (subgraphPath)}}
async getSubgraphEntity<Entity> (entity: new () => Entity, id: string, block?: BlockHeight): Promise<any> {
const data = await this._graphWatcher.getEntity(entity, id, this._relationsMap, block);
async getSubgraphEntity<Entity> (
entity: new () => Entity,
id: string,
block: BlockHeight,
selections: ReadonlyArray<SelectionNode> = []
): Promise<any> {
const data = await this._graphWatcher.getEntity(entity, id, this._relationsMap, block, selections);

return data;
}
Expand All @@ -466,9 +476,13 @@ export class Indexer implements IPLDIndexerInterface {
await this.triggerIndexingOnEvent(event);
}

async processBlock (blockHash: string, blockNumber: number): Promise<void> {
async processBlock (blockProgress: BlockProgress): Promise<void> {
// Call a function to create initial state for contracts.
await this._baseIndexer.createInit(this, blockHash, blockNumber);
await this._baseIndexer.createInit(this, blockProgress.blockHash, blockProgress.blockNumber);

{{#if (subgraphPath)}}
this._graphWatcher.updateEntityCacheFrothyBlocks(blockProgress);
{{/if}}
}

{{#if (subgraphPath)}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class JobRunner {
}

// Process the hooks for the given block number.
await this._indexer.processCanonicalBlock(blockHash);
await this._indexer.processCanonicalBlock(blockHash, blockNumber);

// Update the IPLD status.
await this._indexer.updateIPLDStatusHooksBlock(blockNumber);
Expand Down
12 changes: 9 additions & 3 deletions packages/codegen/src/templates/resolvers-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import assert from 'assert';
import BigInt from 'apollo-type-bigint';
import debug from 'debug';
import Decimal from 'decimal.js';
import { GraphQLScalarType } from 'graphql';
import { GraphQLResolveInfo, GraphQLScalarType } from 'graphql';

import { ValueResult, BlockHeight, gqlTotalQueryCount, gqlQueryCount, jsonBigIntStringReplacer } from '@cerc-io/util';

Expand Down Expand Up @@ -78,12 +78,18 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch
{{/each}}

{{~#each subgraphQueries}}
{{this.queryName}}: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
{{this.queryName}}: async (
_: any,
{ id, block = {} }: { id: string, block: BlockHeight },
__: any,
info: GraphQLResolveInfo
) => {
log('{{this.queryName}}', id, JSON.stringify(block, jsonBigIntStringReplacer));
gqlTotalQueryCount.inc(1);
gqlQueryCount.labels('{{this.queryName}}').inc(1);
assert(info.fieldNodes[0].selectionSet);

return indexer.getSubgraphEntity({{this.entityName}}, id, block);
return indexer.getSubgraphEntity({{this.entityName}}, id, block, info.fieldNodes[0].selectionSet.selections);
},

{{/each}}
Expand Down
29 changes: 18 additions & 11 deletions packages/eden-watcher/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DeepPartial, FindConditions, FindManyOptions } from 'typeorm';
import JSONbig from 'json-bigint';
import { ethers } from 'ethers';
import _ from 'lodash';
import { SelectionNode } from 'graphql';

import { JsonFragment } from '@ethersproject/abi';
import { BaseProvider } from '@ethersproject/providers';
Expand Down Expand Up @@ -264,16 +265,16 @@ export class Indexer implements IPLDIndexerInterface {
return createStateCheckpoint(this, contractAddress, blockHash);
}

async processCanonicalBlock (blockHash: string): Promise<void> {
async processCanonicalBlock (blockHash: string, blockNumber: number): Promise<void> {
console.time('time:indexer#processCanonicalBlock-finalize_auto_diffs');

// Finalize staged diff blocks if any.
await this._baseIndexer.finalizeDiffStaged(blockHash);

console.timeEnd('time:indexer#processCanonicalBlock-finalize_auto_diffs');

// Call custom stateDiff hook.
await createStateDiff(this, blockHash);

this._graphWatcher.pruneEntityCacheFrothyBlocks(blockHash, blockNumber);
}

async processCheckpoint (blockHash: string): Promise<void> {
Expand Down Expand Up @@ -371,14 +372,20 @@ export class Indexer implements IPLDIndexerInterface {
await this._baseIndexer.removeIPLDBlocks(blockNumber, kind);
}

async getSubgraphEntity<Entity> (entity: new () => Entity, id: string, block?: BlockHeight): Promise<any> {
const data = await this._graphWatcher.getEntity(entity, id, this._relationsMap, block);
async getSubgraphEntity<Entity> (entity: new () => Entity, id: string, block: BlockHeight, selections: ReadonlyArray<SelectionNode> = []): Promise<any> {
const data = await this._graphWatcher.getEntity(entity, id, this._relationsMap, block, selections);

return data;
}

async getSubgraphEntities<Entity> (entity: new () => Entity, block: BlockHeight, where: { [key: string]: any } = {}, queryOptions: QueryOptions = {}): Promise<any[]> {
return this._graphWatcher.getEntities(entity, this._relationsMap, block, where, queryOptions);
async getSubgraphEntities<Entity> (
entity: new () => Entity,
block: BlockHeight,
where: { [key: string]: any } = {},
queryOptions: QueryOptions = {},
selections: ReadonlyArray<SelectionNode> = []
): Promise<any[]> {
return this._graphWatcher.getEntities(entity, this._relationsMap, block, where, queryOptions, selections);
}

async triggerIndexingOnEvent (event: Event): Promise<void> {
Expand All @@ -400,13 +407,13 @@ export class Indexer implements IPLDIndexerInterface {
await this.triggerIndexingOnEvent(event);
}

async processBlock (blockHash: string, blockNumber: number): Promise<void> {
async processBlock (blockProgress: BlockProgress): Promise<void> {
console.time('time:indexer#processBlock-init_state');

// Call a function to create initial state for contracts.
await this._baseIndexer.createInit(this, blockHash, blockNumber);

await this._baseIndexer.createInit(this, blockProgress.blockHash, blockProgress.blockNumber);
console.timeEnd('time:indexer#processBlock-init_state');

this._graphWatcher.updateEntityCacheFrothyBlocks(blockProgress);
}

async processBlockAfterEvents (blockHash: string): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion packages/eden-watcher/src/job-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class JobRunner {
}

// Process the hooks for the given block number.
await this._indexer.processCanonicalBlock(blockHash);
await this._indexer.processCanonicalBlock(blockHash, blockNumber);

// Update the IPLD status.
await this._indexer.updateIPLDStatusHooksBlock(blockNumber);
Expand Down
Loading

0 comments on commit 18861ea

Please sign in to comment.