From 96a5321ffe6180df65a9483cfc2075298c5f3fc3 Mon Sep 17 00:00:00 2001 From: bankisan Date: Mon, 4 Dec 2023 18:20:38 +0000 Subject: [PATCH] Reloading ponder.config.ts restarts the ponder app (#466) - Add setup() method to server service to replicate interface of other services - Reload ponder app when config file changes rather than exiting - resetMetrics() method to metrics service --- packages/core/src/Ponder.ts | 26 ++++++++++++++++++++++-- packages/core/src/build/service.ts | 1 - packages/core/src/metrics/service.ts | 4 ++++ packages/core/src/server/service.test.ts | 1 + packages/core/src/server/service.ts | 3 +++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/core/src/Ponder.ts b/packages/core/src/Ponder.ts index 115af2f50..bf6d85458 100644 --- a/packages/core/src/Ponder.ts +++ b/packages/core/src/Ponder.ts @@ -199,7 +199,7 @@ export class Ponder { // One-time setup for some services. await this.syncStore.migrateUp(); - await this.serverService.start(); + this.serverService.setup(); // Finally, load the schema + indexing functions which will trigger // the indexing service to reload (for the first time). @@ -217,6 +217,7 @@ export class Ponder { }, }); this.serverService.registerDevRoutes(); + await this.serverService.start(); await Promise.all( this.syncServices.map(async ({ historical, realtime }) => { @@ -241,6 +242,7 @@ export class Ponder { // If not using `dev`, can kill the build service here to avoid hot reloads. await this.buildService.kill(); + await this.serverService.start(); await Promise.all( this.syncServices.map(async ({ historical, realtime }) => { @@ -302,6 +304,7 @@ export class Ponder { indexingStore: this.indexingStore, }); + this.serverService.setup(); await this.serverService.start(); const { schema, graphqlSchema } = schemaResult; @@ -358,11 +361,30 @@ export class Ponder { private registerServiceDependencies() { this.buildService.on("newConfig", async () => { - this.common.logger.fatal({ + this.common.logger.info({ service: "build", msg: "Detected change in ponder.config.ts", }); + this.common.logger.info({ + service: "app", + msg: "Reloading ponder, killing and restarting services", + }); await this.kill(); + + // Clear all listeners. Will be added back in setup. + this.buildService.clearListeners(); + this.syncServices.forEach(({ historical, realtime }) => { + historical.clearListeners(); + realtime.clearListeners(); + }); + this.syncGatewayService.clearListeners(); + this.serverService.clearListeners(); + this.indexingService.clearListeners(); + this.common.metrics.resetMetrics(); + + await this.setup(); + // NOTE: We know we are in dev mode if the build service is receiving events. Build events are disabled in production. + await this.dev(); }); this.buildService.on("newSchema", async ({ schema, graphqlSchema }) => { diff --git a/packages/core/src/build/service.ts b/packages/core/src/build/service.ts index 51f1f6744..fc83e59d1 100644 --- a/packages/core/src/build/service.ts +++ b/packages/core/src/build/service.ts @@ -171,7 +171,6 @@ export class BuildService extends Emittery { // TODO: Validate config lol this.emit("newConfig", { config }); - return config; } diff --git a/packages/core/src/metrics/service.ts b/packages/core/src/metrics/service.ts index 4c23a72b3..c53239512 100644 --- a/packages/core/src/metrics/service.ts +++ b/packages/core/src/metrics/service.ts @@ -201,4 +201,8 @@ export class MetricsService { async getMetrics() { return await this.registry.metrics(); } + + async resetMetrics() { + this.registry.resetMetrics(); + } } diff --git a/packages/core/src/server/service.test.ts b/packages/core/src/server/service.test.ts index b46e3a967..84a639419 100644 --- a/packages/core/src/server/service.test.ts +++ b/packages/core/src/server/service.test.ts @@ -57,6 +57,7 @@ const setup = async ({ await indexingStore.reload({ schema: s }); const service = new ServerService({ common, indexingStore }); + service.setup(); await service.start(); service.reloadGraphqlSchema({ graphqlSchema }); diff --git a/packages/core/src/server/service.ts b/packages/core/src/server/service.ts index 75a1c936a..e686c3c06 100644 --- a/packages/core/src/server/service.ts +++ b/packages/core/src/server/service.ts @@ -43,6 +43,9 @@ export class ServerService extends Emittery { this.indexingStore = indexingStore; this.port = this.common.options.port; this.app = express(); + } + + setup() { this.registerRoutes(); }