From 0a09abd5cc4ef3ace55aca9a89391e0da1fca59e Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 10:31:50 +1200 Subject: [PATCH 1/9] feat: Add initial script to disable indexer --- runner/scripts/toggle-indexer.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 runner/scripts/toggle-indexer.ts diff --git a/runner/scripts/toggle-indexer.ts b/runner/scripts/toggle-indexer.ts new file mode 100644 index 00000000..61c915d9 --- /dev/null +++ b/runner/scripts/toggle-indexer.ts @@ -0,0 +1,14 @@ +// 1. Assert env vars +// 2. connect to coordinator +// 3. disable +// 4. log and set status? + +const grpc = require('@grpc/grpc-js'); +const protoLoader = require( '@grpc/proto-loader'); + +const packageDefinition = protoLoader.loadSync('../../coordinator/proto/indexer_manager.proto'); +const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); + +const indexerManager = new protoDescriptor.indexer.IndexerManager('localhost:8002', grpc.credentials.createInsecure()); + +indexerManager.disable({ accountId: 'morgs.near', functionName: 'sqs' }, console.log); From a3b4ff7c0ec2184a4dc30196df7528d4cb3aa421 Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 10:48:42 +1200 Subject: [PATCH 2/9] refactor: Configure via argv/env --- runner/scripts/toggle-indexer.ts | 47 +++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/runner/scripts/toggle-indexer.ts b/runner/scripts/toggle-indexer.ts index 61c915d9..1acf69b2 100644 --- a/runner/scripts/toggle-indexer.ts +++ b/runner/scripts/toggle-indexer.ts @@ -3,12 +3,51 @@ // 3. disable // 4. log and set status? +/* + * This script is used to suspend an indexer for a given account. It will: + * 1. Call Coordinator to disable the indexer + * 2. Write to the Indexers logs table to notify of suspension + * + * Usage: node toggle-indexer.js + * +*/ + +const assert = require('assert'); +const fs = require('fs'); + const grpc = require('@grpc/grpc-js'); const protoLoader = require( '@grpc/proto-loader'); -const packageDefinition = protoLoader.loadSync('../../coordinator/proto/indexer_manager.proto'); -const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); +const COORDINATOR_PROTO_PATH = '../../coordinator/proto/indexer_manager.proto'; + +assert(exists(COORDINATOR_PROTO_PATH), 'Coordinator proto file not found. Make sure you run this script from the `./scripts` directory.'); +assert(process.argv.length === 4, 'Usage: node toggle-indexer.js '); +assert(process.env.COORDINATOR_PORT, 'COORDINATOR_PORT env var is required'); + +const [_binary, _file, accountId, functionName] = process.argv; +const { COORDINATOR_PORT } = process.env; + +main(); + +function main() { + console.log(`Disabling indexer: ${accountId}/${functionName}\n`); + + const indexerManager = createIndexerManagerClient(); + + indexerManager.diable({ accountId: 'morgs.near', functionName: 'sqs' }, console.log); +} -const indexerManager = new protoDescriptor.indexer.IndexerManager('localhost:8002', grpc.credentials.createInsecure()); +function exists(path) { + try { + fs.statSync(path); + return true; + } catch (err) { + return false; + } +} -indexerManager.disable({ accountId: 'morgs.near', functionName: 'sqs' }, console.log); +function createIndexerManagerClient() { + const packageDefinition = protoLoader.loadSync(COORDINATOR_PROTO_PATH); + const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); + return new protoDescriptor.indexer.IndexerManager(`localhost:${COORDINATOR_PORT}`, grpc.credentials.createInsecure()); +} From 60417237c685e16741890b72e7f8c4f64e40a93a Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 10:56:45 +1200 Subject: [PATCH 3/9] refactor: Rename `toggle` > `suspend` --- runner/scripts/{toggle-indexer.ts => suspend-indexer.ts} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename runner/scripts/{toggle-indexer.ts => suspend-indexer.ts} (90%) diff --git a/runner/scripts/toggle-indexer.ts b/runner/scripts/suspend-indexer.ts similarity index 90% rename from runner/scripts/toggle-indexer.ts rename to runner/scripts/suspend-indexer.ts index 1acf69b2..0dec7967 100644 --- a/runner/scripts/toggle-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -8,7 +8,7 @@ * 1. Call Coordinator to disable the indexer * 2. Write to the Indexers logs table to notify of suspension * - * Usage: node toggle-indexer.js + * Usage: node suspend-indexer.ts * */ @@ -21,7 +21,7 @@ const protoLoader = require( '@grpc/proto-loader'); const COORDINATOR_PROTO_PATH = '../../coordinator/proto/indexer_manager.proto'; assert(exists(COORDINATOR_PROTO_PATH), 'Coordinator proto file not found. Make sure you run this script from the `./scripts` directory.'); -assert(process.argv.length === 4, 'Usage: node toggle-indexer.js '); +assert(process.argv.length === 4, 'Usage: node suspend-indexer.ts '); assert(process.env.COORDINATOR_PORT, 'COORDINATOR_PORT env var is required'); const [_binary, _file, accountId, functionName] = process.argv; From 6baad44168c0549266d2f9833fc144a4328e31f3 Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 11:01:45 +1200 Subject: [PATCH 4/9] refactor: Convert to TS --- runner/scripts/suspend-indexer.ts | 14 +++++++------- runner/tsconfig.build.json | 2 +- runner/tsconfig.json | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/runner/scripts/suspend-indexer.ts b/runner/scripts/suspend-indexer.ts index 0dec7967..adb8b13d 100644 --- a/runner/scripts/suspend-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -12,11 +12,11 @@ * */ -const assert = require('assert'); -const fs = require('fs'); +import assert from 'assert' +import * as fs from 'fs' -const grpc = require('@grpc/grpc-js'); -const protoLoader = require( '@grpc/proto-loader'); +import * as grpc from '@grpc/grpc-js' +import * as protoLoader from '@grpc/proto-loader' const COORDINATOR_PROTO_PATH = '../../coordinator/proto/indexer_manager.proto'; @@ -34,10 +34,10 @@ function main() { const indexerManager = createIndexerManagerClient(); - indexerManager.diable({ accountId: 'morgs.near', functionName: 'sqs' }, console.log); + indexerManager.disable({ accountId: 'morgs.near', functionName: 'sqs' }, console.log); } -function exists(path) { +function exists(path: string): boolean { try { fs.statSync(path); return true; @@ -48,6 +48,6 @@ function exists(path) { function createIndexerManagerClient() { const packageDefinition = protoLoader.loadSync(COORDINATOR_PROTO_PATH); - const protoDescriptor = grpc.loadPackageDefinition(packageDefinition); + const protoDescriptor: any = grpc.loadPackageDefinition(packageDefinition); return new protoDescriptor.indexer.IndexerManager(`localhost:${COORDINATOR_PORT}`, grpc.credentials.createInsecure()); } diff --git a/runner/tsconfig.build.json b/runner/tsconfig.build.json index d37e1cd7..dfbf07a6 100644 --- a/runner/tsconfig.build.json +++ b/runner/tsconfig.build.json @@ -1,5 +1,5 @@ { "extends": "./tsconfig.json", "include": ["./src"], - "exclude": ["node_modules", "dist", "**/*.test.*"] + "exclude": ["node_modules", "dist", "**/*.test.*", "scripts"] } diff --git a/runner/tsconfig.json b/runner/tsconfig.json index 4e64096a..d4949c0e 100644 --- a/runner/tsconfig.json +++ b/runner/tsconfig.json @@ -3,7 +3,7 @@ "target": "es2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "lib": ["es2021"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ "module": "commonjs", /* Specify what module code is generated. */ - "rootDirs": ["./src", "./tests"], + "rootDirs": ["./src", "./tests", "./scripts"], "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ "resolveJsonModule": true, /* Enable importing .json files. */ "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ @@ -20,6 +20,6 @@ "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ }, - "include": ["./src", "./tests"], + "include": ["./src", "./tests", "./scripts"], "exclude": ["node_modules", "dist"] } From d637a099524d9c418c899a2fe24e8e399964575a Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 11:25:43 +1200 Subject: [PATCH 5/9] refactor: Add npm script for easier src/ integration --- runner/package.json | 3 ++- runner/scripts/suspend-indexer.ts | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/runner/package.json b/runner/package.json index 87b21b96..3cc4f15b 100644 --- a/runner/package.json +++ b/runner/package.json @@ -14,7 +14,8 @@ "start:dev": "tsc -p ./tsconfig.build.json && node ./dist", "start:docker": "node dist/index.js", "test": "npm run codegen && node --experimental-vm-modules ./node_modules/.bin/jest --silent", - "lint": "eslint -c .eslintrc.js" + "lint": "eslint -c .eslintrc.js", + "script:suspend-indexer": "tsc -p ./tsconfig.json && node ./dist/scripts/suspend-indexer.js" }, "keywords": [], "author": "", diff --git a/runner/scripts/suspend-indexer.ts b/runner/scripts/suspend-indexer.ts index adb8b13d..ccc29131 100644 --- a/runner/scripts/suspend-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -8,7 +8,7 @@ * 1. Call Coordinator to disable the indexer * 2. Write to the Indexers logs table to notify of suspension * - * Usage: node suspend-indexer.ts + * Usage: npm run script:suspend-indexer -- * */ @@ -18,10 +18,10 @@ import * as fs from 'fs' import * as grpc from '@grpc/grpc-js' import * as protoLoader from '@grpc/proto-loader' -const COORDINATOR_PROTO_PATH = '../../coordinator/proto/indexer_manager.proto'; +const COORDINATOR_PROTO_PATH = '../coordinator/proto/indexer_manager.proto'; -assert(exists(COORDINATOR_PROTO_PATH), 'Coordinator proto file not found. Make sure you run this script from the `./scripts` directory.'); -assert(process.argv.length === 4, 'Usage: node suspend-indexer.ts '); +assert(exists(COORDINATOR_PROTO_PATH), 'Coordinator proto file not found. Make sure you run this script from the root directory.'); +assert(process.argv.length === 4, 'Usage: npm run script:suspend-indexer -- '); assert(process.env.COORDINATOR_PORT, 'COORDINATOR_PORT env var is required'); const [_binary, _file, accountId, functionName] = process.argv; From d0eeb55aa4b7e38c47fe453844ee7d17248974e9 Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 11:52:22 +1200 Subject: [PATCH 6/9] feat: Log suspension --- runner/scripts/suspend-indexer.ts | 29 ++++++++++++++++++++++++++--- runner/src/indexer-meta/index.ts | 1 + 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/runner/scripts/suspend-indexer.ts b/runner/scripts/suspend-indexer.ts index ccc29131..d85333df 100644 --- a/runner/scripts/suspend-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -18,23 +18,46 @@ import * as fs from 'fs' import * as grpc from '@grpc/grpc-js' import * as protoLoader from '@grpc/proto-loader' +import Provisioner from '../src/provisioner' +import IndexerConfig from '../src/indexer-config' +import IndexerMeta, { LogEntry } from '../src/indexer-meta'; + const COORDINATOR_PROTO_PATH = '../coordinator/proto/indexer_manager.proto'; assert(exists(COORDINATOR_PROTO_PATH), 'Coordinator proto file not found. Make sure you run this script from the root directory.'); assert(process.argv.length === 4, 'Usage: npm run script:suspend-indexer -- '); assert(process.env.COORDINATOR_PORT, 'COORDINATOR_PORT env var is required'); +assert(process.env.HASURA_ADMIN_SECRET, 'HASURA_ADMIN_SECRET env var is required'); +assert(process.env.HASURA_ENDPOINT, 'HASURA_ENDPOINT env var is required'); +assert(process.env.PGPORT, 'PGPORT env var is required'); +assert(process.env.PGHOST, 'PGHOST env var is required'); const [_binary, _file, accountId, functionName] = process.argv; const { COORDINATOR_PORT } = process.env; +const provisioner = new Provisioner(); + main(); -function main() { - console.log(`Disabling indexer: ${accountId}/${functionName}\n`); +async function main() { + const config = new IndexerConfig('redis stream', accountId, functionName, 0, 'code', 'schema', 2); + + console.log(`Suspending indexer: ${accountId}/${functionName}\n`); const indexerManager = createIndexerManagerClient(); - indexerManager.disable({ accountId: 'morgs.near', functionName: 'sqs' }, console.log); + indexerManager.disable({ accountId, functionName }, console.log); + + console.log('Logging suspension notification'); + + const pgCredentials = await provisioner.getPostgresConnectionParameters(config.userName()); + const meta = new IndexerMeta(config, pgCredentials); + + await meta.writeLogs([ + LogEntry.systemInfo('Suspending Indexer due to inactivity'), + ]); + + console.log('Done') } function exists(path: string): boolean { diff --git a/runner/src/indexer-meta/index.ts b/runner/src/indexer-meta/index.ts index a6bf324c..05406387 100644 --- a/runner/src/indexer-meta/index.ts +++ b/runner/src/indexer-meta/index.ts @@ -1,2 +1,3 @@ export { default } from './indexer-meta'; export { IndexerStatus, METADATA_TABLE_UPSERT, MetadataFields } from './indexer-meta'; +export { default as LogEntry } from './log-entry'; From 673bf4b908d36ec530c6f5be3500dfa0c119b96e Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 14:03:09 +1200 Subject: [PATCH 7/9] fix: Wait for suspension to finish before continuing --- runner/scripts/suspend-indexer.ts | 36 ++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/runner/scripts/suspend-indexer.ts b/runner/scripts/suspend-indexer.ts index d85333df..a2513456 100644 --- a/runner/scripts/suspend-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -35,29 +35,41 @@ assert(process.env.PGHOST, 'PGHOST env var is required'); const [_binary, _file, accountId, functionName] = process.argv; const { COORDINATOR_PORT } = process.env; -const provisioner = new Provisioner(); - main(); async function main() { - const config = new IndexerConfig('redis stream', accountId, functionName, 0, 'code', 'schema', 2); + await suspendIndexer(); + await logSuspension(); - console.log(`Suspending indexer: ${accountId}/${functionName}\n`); - - const indexerManager = createIndexerManagerClient(); - - indexerManager.disable({ accountId, functionName }, console.log); + console.log('Done') +} +async function logSuspension() { console.log('Logging suspension notification'); - const pgCredentials = await provisioner.getPostgresConnectionParameters(config.userName()); - const meta = new IndexerMeta(config, pgCredentials); + const config = new IndexerConfig('redis stream', accountId, functionName, 0, 'code', 'schema', 2); + + const pgCredentials = await new Provisioner().getPostgresConnectionParameters(config.userName()); - await meta.writeLogs([ + await new IndexerMeta(config, pgCredentials).writeLogs([ LogEntry.systemInfo('Suspending Indexer due to inactivity'), ]); +} - console.log('Done') +async function suspendIndexer() { + console.log(`Suspending indexer: ${accountId}/${functionName}`); + + const indexerManager = createIndexerManagerClient(); + + return new Promise((resolve, reject) => { + indexerManager.disable({ accountId, functionName }, (err: any, response: any) => { + if (err) { + reject(err); + } else { + resolve(response); + } + }); + }) } function exists(path: string): boolean { From 2a472dd06de8f1542b381cde64efe4dc879da4b2 Mon Sep 17 00:00:00 2001 From: Morgan Mccauley Date: Mon, 24 Jun 2024 14:50:25 +1200 Subject: [PATCH 8/9] chore: Update script notes --- runner/scripts/suspend-indexer.ts | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/runner/scripts/suspend-indexer.ts b/runner/scripts/suspend-indexer.ts index a2513456..8fb2f321 100644 --- a/runner/scripts/suspend-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -1,15 +1,27 @@ -// 1. Assert env vars -// 2. connect to coordinator -// 3. disable -// 4. log and set status? - /* * This script is used to suspend an indexer for a given account. It will: * 1. Call Coordinator to disable the indexer * 2. Write to the Indexers logs table to notify of suspension * + * Note that as Coordinator is in a private network, you must tunnel to the machine to expose the gRPC server. + * This can be achieved via running the following in a separate terminal: + * ```sh + * gcloud compute ssh ubuntu@queryapi-coordinator-mainnet -- -L 9003:0.0.0.0:9003 + * ``` + * + * The following environment variables are required: + * - `HASURA_ADMIN_SECRET` + * - `HASURA_ENDPOINT` + * - `PGPORT` + * - `PGHOST` + * + * All of which can be found in the Runner compute instance metadata: + * ```sh + * gcloud compute instances describe queryapi-runner-mainnet + * ``` + * + * * Usage: npm run script:suspend-indexer -- - * */ import assert from 'assert' @@ -33,7 +45,7 @@ assert(process.env.PGPORT, 'PGPORT env var is required'); assert(process.env.PGHOST, 'PGHOST env var is required'); const [_binary, _file, accountId, functionName] = process.argv; -const { COORDINATOR_PORT } = process.env; +const { COORDINATOR_PORT = 9003 } = process.env; main(); @@ -47,7 +59,7 @@ async function main() { async function logSuspension() { console.log('Logging suspension notification'); - const config = new IndexerConfig('redis stream', accountId, functionName, 0, 'code', 'schema', 2); + const config = new IndexerConfig('not needed', accountId, functionName, 0, 'not needed', 'not needed', 2); const pgCredentials = await new Provisioner().getPostgresConnectionParameters(config.userName()); From 07fe8686a0bdd754fd611a79fe3af4dc75c67abd Mon Sep 17 00:00:00 2001 From: Morgan McCauley Date: Wed, 26 Jun 2024 10:40:27 +1200 Subject: [PATCH 9/9] Update runner/scripts/suspend-indexer.ts --- runner/scripts/suspend-indexer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runner/scripts/suspend-indexer.ts b/runner/scripts/suspend-indexer.ts index 8fb2f321..060339a2 100644 --- a/runner/scripts/suspend-indexer.ts +++ b/runner/scripts/suspend-indexer.ts @@ -64,7 +64,7 @@ async function logSuspension() { const pgCredentials = await new Provisioner().getPostgresConnectionParameters(config.userName()); await new IndexerMeta(config, pgCredentials).writeLogs([ - LogEntry.systemInfo('Suspending Indexer due to inactivity'), + LogEntry.systemInfo('The indexer is suspended due to inactivity.'), ]); }