Add config for GQL requests cache (#228)

* Add config and a method to set cache control settings for GQL requests

* Add option for max size in GQL cache config

* Fix failing tests
This commit is contained in:
prathamesh0 2022-11-15 03:26:08 -06:00 committed by GitHub
parent 6f8ededd52
commit a52bdf64b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 40 deletions

View File

@ -3,13 +3,13 @@
//
import { BaseProvider } from '@ethersproject/providers';
import { getCustomProvider, Database as BaseDatabase } from '@cerc-io/util';
import { getCustomProvider, Database as BaseDatabase, ServerConfig } from '@cerc-io/util';
import { EthClient } from '@cerc-io/ipld-eth-client';
import { StorageLayout } from '@cerc-io/solidity-mapper';
import { EventData } from '../../src/utils';
import { Database } from '../../src/database';
import { Indexer, ServerConfig } from './indexer';
import { Indexer } from './indexer';
const NETWORK_URL = 'http://127.0.0.1:8081';
const IPLD_ETH_SERVER_GQL_URL = 'http://127.0.0.1:8082/graphql';
@ -72,7 +72,7 @@ export const getDummyGraphData = (): any => {
export const getTestDatabase = (): Database => {
const baseDatabase = new BaseDatabase({ type: 'postgres' });
const serverConfig = new ServerConfig();
const serverConfig = {} as ServerConfig;
return new Database(serverConfig, baseDatabase);
};

View File

@ -6,7 +6,7 @@ import {
BlockProgressInterface,
EventInterface,
SyncStatusInterface,
ServerConfig as ServerConfigInterface,
ServerConfig,
ValueResult,
ContractInterface,
StateStatus,
@ -29,7 +29,7 @@ export class Indexer implements IndexerInterface {
}
get serverConfig () {
return new ServerConfig();
return {} as ServerConfig;
}
get storageLayoutMap (): Map<string, StorageLayout> {
@ -202,37 +202,3 @@ export class Indexer implements IndexerInterface {
return undefined;
}
}
export class ServerConfig implements ServerConfigInterface {
host: string;
port: number;
mode: string;
kind: string;
checkpointing: boolean;
checkpointInterval: number;
subgraphPath: string;
enableState: boolean;
wasmRestartBlocksInterval: number;
filterLogs: boolean;
maxEventsBlockRange: number;
clearEntitiesCacheInterval: number;
skipStateFieldsUpdate: boolean;
loadRelationsSequential: boolean;
constructor () {
this.host = '';
this.port = 0;
this.mode = '';
this.kind = '';
this.checkpointing = false;
this.checkpointInterval = 0;
this.subgraphPath = '';
this.enableState = false;
this.wasmRestartBlocksInterval = 0;
this.filterLogs = false;
this.maxEventsBlockRange = 0;
this.clearEntitiesCacheInterval = 0;
this.skipStateFieldsUpdate = false;
this.loadRelationsSequential = false;
}
}

View File

@ -29,6 +29,13 @@ export interface JobQueueConfig {
prefetchBlockCount: number;
}
export interface GQLCacheConfig {
enabled: boolean;
maxCacheSize?: number;
maxAge: number;
timeTravelMaxAge: number;
}
export interface ServerConfig {
host: string;
port: number;
@ -54,6 +61,9 @@ export interface ServerConfig {
// Boolean to load GQL query nested entity relations sequentially.
loadRelationsSequential: boolean;
// GQL cache-control max-age settings (in seconds)
gqlCache: GQLCacheConfig
}
export interface UpstreamConfig {

View File

@ -23,3 +23,5 @@ export const UNKNOWN_EVENT_NAME = '__unknown__';
export const KIND_ACTIVE = 'active';
export const KIND_LAZY = 'lazy';
export const DEFAULT_MAX_GQL_CACHE_SIZE = Math.pow(2, 20) * 8; // 8 MB

View File

@ -9,17 +9,20 @@ import { hideBin } from 'yargs/helpers';
import { utils, providers } from 'ethers';
import JSONbig from 'json-bigint';
import Decimal from 'decimal.js';
import { GraphQLResolveInfo } from 'graphql';
import _ from 'lodash';
import { EthClient } from '@cerc-io/ipld-eth-client';
import { DEFAULT_CONFIG_PATH } from './constants';
import { Config } from './config';
import { GQLCacheConfig, Config } from './config';
import { JobQueue } from './job-queue';
import { GraphDecimal } from './graph-decimal';
import * as EthDecoder from './eth';
import { getCachedBlockSize } from './block-size-cache';
import { ResultEvent } from './indexer';
import { EventInterface } from './types';
import { BlockHeight } from './database';
const JSONbigNative = JSONbig({ useNativeBigInt: true });
@ -287,3 +290,15 @@ export const getResultEvent = (event: EventInterface): ResultEvent => {
proof: JSON.parse(event.proof)
};
};
export const setGQLCacheHints = (info: GraphQLResolveInfo, block: BlockHeight, gqlCache: GQLCacheConfig): void => {
if (!gqlCache || !gqlCache.enabled) {
return;
}
assert(gqlCache.maxAge, 'Missing server gqlCache.maxAge');
assert(gqlCache.timeTravelMaxAge, 'Missing server gqlCache.timeTravelMaxAge');
const maxAge = _.isEmpty(block) ? gqlCache.maxAge : gqlCache.timeTravelMaxAge;
info.cacheControl.setCacheHint({ maxAge });
};