From 601bb36fb86ceb4caa8255acd5be336a0dce5f79 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Thu, 21 Jul 2022 10:20:56 +0100 Subject: [PATCH] Fix a race condition whereby the healthcheck is reporting good because it hasn't run yet --- app/server.js | 5 +++-- app/utils/ServiceWatcher.js | 20 +++++++++++++------- helm/dscp-ipfs/Chart.yaml | 4 ++-- helm/dscp-ipfs/values.yaml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- test/unit/ServiceWatcher.test.js | 4 ++-- 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/app/server.js b/app/server.js index 57fa913..8ae6ce6 100644 --- a/app/server.js +++ b/app/server.js @@ -15,9 +15,10 @@ async function createHttpServer() { const api = await createNodeApi() const sw = new ServiceWatcher({ - substrate: { healthCheck: () => nodeHealthCheck({ api, isReady: false }) }, + substrate: { healthCheck: () => nodeHealthCheck(api._api) }, ipfs: { healthCheck: () => ipfsHealthCheack(ipfs) }, }) + await sw.start() await setupKeyWatcher({ api, @@ -60,7 +61,6 @@ async function startServer() { const server = app.listen(PORT, (err) => { if (err) return reject(err) logger.info(`Listening on port ${PORT} `) - sw.start() resolve(server) }) @@ -68,6 +68,7 @@ async function startServer() { }) const closeHandler = (exitCode) => async () => { + sw.gen.return() server.close(async () => { await ipfs.stop() process.exit(exitCode) diff --git a/app/utils/ServiceWatcher.js b/app/utils/ServiceWatcher.js index 4f9348e..5b928f2 100644 --- a/app/utils/ServiceWatcher.js +++ b/app/utils/ServiceWatcher.js @@ -44,29 +44,35 @@ class ServiceWatcher { .filter(Boolean) } - // fire and forget, cancel using ServiceWatcher.gen.return() - // or ServiceWatcher.gen.throw() - start() { + // starts the generator resolving after the first update + // use ServiceWatcher.gen.return() to stop + async start() { if (this.services.length < 1) return null this.gen = this.#generator() - const recursive = async (getAll = Promise.resolve([])) => { + const update = async (getAll = Promise.resolve([])) => { try { const services = await getAll services.forEach(({ name, ...rest }) => this.update(name, rest)) - await this.delay(this.#pollPeriod) } catch (error) { // if no service assume that this is server error e.g. TypeError, Parse... const name = error.service || 'server' this.update(name, { error, status: 'error' }) } + } + const recursive = async () => { + await this.delay(this.#pollPeriod) const { value } = this.gen.next() - if (value) return recursive(value) + if (value) { + await update(value) + return recursive() + } } const { value } = this.gen.next() - recursive(value) + await update(value) + recursive() } // a generator function that returns poll fn for each service diff --git a/helm/dscp-ipfs/Chart.yaml b/helm/dscp-ipfs/Chart.yaml index d21662f..b467b6d 100644 --- a/helm/dscp-ipfs/Chart.yaml +++ b/helm/dscp-ipfs/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 name: dscp-ipfs -appVersion: '2.6.0' +appVersion: '2.6.1' description: A Helm chart for dscp-ipfs -version: '2.6.0' +version: '2.6.1' type: application dependencies: - name: dscp-node diff --git a/helm/dscp-ipfs/values.yaml b/helm/dscp-ipfs/values.yaml index ab4f4bd..0fe7101 100644 --- a/helm/dscp-ipfs/values.yaml +++ b/helm/dscp-ipfs/values.yaml @@ -52,7 +52,7 @@ statefulSet: image: repository: digicatapult/dscp-ipfs pullPolicy: IfNotPresent - tag: 'v2.6.0' + tag: 'v2.6.1' storage: storageClass: "" diff --git a/package-lock.json b/package-lock.json index 728253b..8c1bed8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@digicatapult/dscp-ipfs", - "version": "2.6.0", + "version": "2.6.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@digicatapult/dscp-ipfs", - "version": "2.6.0", + "version": "2.6.1", "license": "Apache-2.0", "dependencies": { "@digicatapult/dscp-node": "^4.2.1", diff --git a/package.json b/package.json index 4523bef..6c7de27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@digicatapult/dscp-ipfs", - "version": "2.6.0", + "version": "2.6.1", "description": "Service for DSCP", "main": "app/index.js", "scripts": { diff --git a/test/unit/ServiceWatcher.test.js b/test/unit/ServiceWatcher.test.js index 046b126..fe1befe 100644 --- a/test/unit/ServiceWatcher.test.js +++ b/test/unit/ServiceWatcher.test.js @@ -233,11 +233,11 @@ describe('ServiceWatcher', function () { beforeEach(async () => { SW = new ServiceWatcher({ substrate: substrate.timeout }) spy(SW, 'update') - SW.start() // using await so it hits timeout + await SW.start() // using await so it hits timeout await SW.delay(3000) }) - it('creates an instace of timeout error with error message', () => { + it('creates an instance of timeout error with error message', () => { const { error } = SW.report.substrate expect(error).to.be.a.instanceOf(TimeoutError)