2021-11-16 09:17:03 +00:00
|
|
|
//
|
|
|
|
// Copyright 2021 Vulcanize, Inc.
|
|
|
|
//
|
|
|
|
|
|
|
|
import fs from 'fs';
|
|
|
|
import path from 'path';
|
|
|
|
import assert from 'assert';
|
|
|
|
import 'reflect-metadata';
|
|
|
|
import express, { Application } from 'express';
|
2022-11-16 05:44:54 +00:00
|
|
|
import { PubSub } from 'graphql-subscriptions';
|
2021-11-16 09:17:03 +00:00
|
|
|
import yargs from 'yargs';
|
|
|
|
import { hideBin } from 'yargs/helpers';
|
|
|
|
import debug from 'debug';
|
|
|
|
import 'graphql-import-node';
|
|
|
|
|
2022-11-17 06:32:08 +00:00
|
|
|
import { DEFAULT_CONFIG_PATH, getConfig, Config, JobQueue, KIND_ACTIVE, initClients, startGQLMetricsServer, createAndStartServer } from '@cerc-io/util';
|
2022-09-09 11:43:01 +00:00
|
|
|
import { GraphWatcher, Database as GraphDatabase } from '@cerc-io/graph-node';
|
2021-11-16 09:17:03 +00:00
|
|
|
|
|
|
|
import { createResolvers } from './resolvers';
|
|
|
|
import { Indexer } from './indexer';
|
2022-11-17 04:44:59 +00:00
|
|
|
import { Database, ENTITY_TO_LATEST_ENTITY_MAP } from './database';
|
2021-11-16 09:17:03 +00:00
|
|
|
import { EventWatcher } from './events';
|
|
|
|
|
|
|
|
const log = debug('vulcanize:server');
|
|
|
|
|
|
|
|
export const main = async (): Promise<any> => {
|
|
|
|
const argv = await yargs(hideBin(process.argv))
|
|
|
|
.option('f', {
|
|
|
|
alias: 'config-file',
|
|
|
|
demandOption: true,
|
|
|
|
describe: 'configuration file path (toml)',
|
|
|
|
type: 'string',
|
|
|
|
default: DEFAULT_CONFIG_PATH
|
|
|
|
})
|
|
|
|
.argv;
|
|
|
|
|
|
|
|
const config: Config = await getConfig(argv.f);
|
2022-06-08 06:43:52 +00:00
|
|
|
const { ethClient, ethProvider } = await initClients(config);
|
2021-11-16 09:17:03 +00:00
|
|
|
|
2022-11-16 14:31:18 +00:00
|
|
|
const { kind: watcherKind } = config.server;
|
2021-11-16 09:17:03 +00:00
|
|
|
|
|
|
|
const db = new Database(config.database);
|
|
|
|
await db.init();
|
|
|
|
|
2022-11-17 04:44:59 +00:00
|
|
|
const graphDb = new GraphDatabase(config.server, db.baseDatabase, ENTITY_TO_LATEST_ENTITY_MAP);
|
2021-11-16 09:17:03 +00:00
|
|
|
await graphDb.init();
|
|
|
|
|
2022-06-08 06:43:52 +00:00
|
|
|
const graphWatcher = new GraphWatcher(graphDb, ethClient, ethProvider, config.server);
|
2021-11-16 09:17:03 +00:00
|
|
|
|
|
|
|
// Note: In-memory pubsub works fine for now, as each watcher is a single process anyway.
|
|
|
|
// Later: https://www.apollographql.com/docs/apollo-server/data/subscriptions/#production-pubsub-libraries
|
|
|
|
const pubsub = new PubSub();
|
|
|
|
|
|
|
|
const jobQueueConfig = config.jobQueue;
|
|
|
|
assert(jobQueueConfig, 'Missing job queue config');
|
|
|
|
|
|
|
|
const { dbConnectionString, maxCompletionLagInSecs } = jobQueueConfig;
|
|
|
|
assert(dbConnectionString, 'Missing job queue db connection string');
|
|
|
|
|
|
|
|
const jobQueue = new JobQueue({ dbConnectionString, maxCompletionLag: maxCompletionLagInSecs });
|
|
|
|
|
2022-11-21 07:47:23 +00:00
|
|
|
const indexer = new Indexer(config.server, db, { ethClient }, ethProvider, jobQueue, graphWatcher);
|
2021-12-13 10:56:01 +00:00
|
|
|
await indexer.init();
|
2021-11-18 12:33:36 +00:00
|
|
|
|
|
|
|
graphWatcher.setIndexer(indexer);
|
|
|
|
await graphWatcher.init();
|
|
|
|
|
2022-11-22 11:11:15 +00:00
|
|
|
const eventWatcher = new EventWatcher(ethClient, indexer, pubsub, jobQueue);
|
2021-11-16 09:17:03 +00:00
|
|
|
|
|
|
|
if (watcherKind === KIND_ACTIVE) {
|
|
|
|
await jobQueue.start();
|
2022-11-03 08:31:10 +00:00
|
|
|
// Delete jobs to prevent creating jobs after completion of processing previous block.
|
|
|
|
await jobQueue.deleteAllJobs();
|
2021-11-16 09:17:03 +00:00
|
|
|
await eventWatcher.start();
|
|
|
|
}
|
|
|
|
|
|
|
|
const resolvers = await createResolvers(indexer, eventWatcher);
|
|
|
|
const typeDefs = fs.readFileSync(path.join(__dirname, 'schema.gql')).toString();
|
|
|
|
|
2022-11-16 05:44:54 +00:00
|
|
|
// Create an Express app
|
|
|
|
const app: Application = express();
|
2022-11-17 06:32:08 +00:00
|
|
|
const server = createAndStartServer(app, typeDefs, resolvers, config.server);
|
2021-11-16 09:17:03 +00:00
|
|
|
|
2022-09-01 08:47:43 +00:00
|
|
|
startGQLMetricsServer(config);
|
|
|
|
|
2021-11-16 09:17:03 +00:00
|
|
|
return { app, server };
|
|
|
|
};
|
|
|
|
|
|
|
|
main().then(() => {
|
|
|
|
log('Starting server...');
|
|
|
|
}).catch(err => {
|
|
|
|
log(err);
|
|
|
|
});
|