From c436ec97af252b9371372d4f1e118cbdc7c8ea68 Mon Sep 17 00:00:00 2001 From: Arash Shakery Date: Tue, 9 Mar 2021 00:23:39 +0330 Subject: [PATCH 1/3] stop previous apolloServer before creating a new one This causes socket listeners to close gracefully. Fixes issues #51 and #74 --- src/service.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/service.js b/src/service.js index fb7385e..77eb5e4 100644 --- a/src/service.js +++ b/src/service.js @@ -612,6 +612,10 @@ module.exports = function (mixinOptions) { if (!this.shouldUpdateGraphqlSchema && this.graphqlHandler) { return; } + + if (this.apolloServer) { + this.apolloServer.stop(); + } // Create new server & regenerate GraphQL schema this.logger.info( From 6563b7785ddb70a7e58cb36c0fe26307b8fdf648 Mon Sep 17 00:00:00 2001 From: Arash Shakery Date: Fri, 12 Mar 2021 03:00:28 +0330 Subject: [PATCH 2/3] await appoloServer to stop, before starting a new one --- src/service.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/service.js b/src/service.js index 77eb5e4..41d8119 100644 --- a/src/service.js +++ b/src/service.js @@ -607,14 +607,14 @@ module.exports = function (mixinOptions) { /** * Prepare GraphQL schemas based on Moleculer services. */ - prepareGraphQLSchema() { + async prepareGraphQLSchema() { // Schema is up-to-date if (!this.shouldUpdateGraphqlSchema && this.graphqlHandler) { return; } - + if (this.apolloServer) { - this.apolloServer.stop(); + await this.apolloServer.stop(); } // Create new server & regenerate GraphQL schema @@ -734,17 +734,17 @@ module.exports = function (mixinOptions) { const route = _.defaultsDeep(mixinOptions.routeOptions, { aliases: { - "/"(req, res) { + async "/"(req, res) { try { - this.prepareGraphQLSchema(); + await this.prepareGraphQLSchema(); return this.graphqlHandler(req, res); } catch (err) { this.sendError(req, res, err); } }, - "GET /.well-known/apollo/server-health"(req, res) { + async "GET /.well-known/apollo/server-health"(req, res) { try { - this.prepareGraphQLSchema(); + await this.prepareGraphQLSchema(); } catch (err) { res.statusCode = 503; return this.sendResponse( @@ -783,8 +783,8 @@ module.exports = function (mixinOptions) { query: { type: "string" }, variables: { type: "object", optional: true }, }, - handler(ctx) { - this.prepareGraphQLSchema(); + async handler(ctx) { + await this.prepareGraphQLSchema(); return GraphQL.graphql( this.graphqlSchema, ctx.params.query, From dc915d3ccc2662e9bc090d1eb92ef897bcac37c1 Mon Sep 17 00:00:00 2001 From: Shawn McKnight Date: Sat, 20 Mar 2021 13:02:14 -0400 Subject: [PATCH 3/3] Fix failing tests and lint errors --- test/unit/service.spec.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/unit/service.spec.js b/test/unit/service.spec.js index e42a6f3..d7a9703 100644 --- a/test/unit/service.spec.js +++ b/test/unit/service.spec.js @@ -35,7 +35,7 @@ async function startService(mixinOptions, baseSchema) { describe("Test Service", () => { describe("Test created handler", () => { it("should register a route with default options", async () => { - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); expect(svc.shouldUpdateGraphqlSchema).toBe(true); @@ -59,7 +59,7 @@ describe("Test Service", () => { describe("Test `/` route handler", () => { it("should prepare graphql schema & call handler", async () => { - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); // Test `/` alias svc.prepareGraphQLSchema = jest.fn(); @@ -67,7 +67,7 @@ describe("Test Service", () => { const fakeReq = { req: 1 }; const fakeRes = { res: 1 }; - const res = svc.settings.routes[0].aliases["/"].call(svc, fakeReq, fakeRes); + const res = await svc.settings.routes[0].aliases["/"].call(svc, fakeReq, fakeRes); expect(res).toBe("result"); expect(svc.prepareGraphQLSchema).toBeCalledTimes(1); @@ -78,7 +78,7 @@ describe("Test Service", () => { }); it("should call sendError if error occured", async () => { - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); const err = new Error("Something happened"); svc.sendError = jest.fn(); @@ -89,7 +89,7 @@ describe("Test Service", () => { const fakeReq = { req: 1 }; const fakeRes = { res: 1 }; - const res = svc.settings.routes[0].aliases["/"].call(svc, fakeReq, fakeRes); + const res = await svc.settings.routes[0].aliases["/"].call(svc, fakeReq, fakeRes); expect(res).toBeUndefined(); expect(svc.prepareGraphQLSchema).toBeCalledTimes(1); @@ -103,7 +103,7 @@ describe("Test Service", () => { describe("Test `GET /.well-known/apollo/server-health` route handler", () => { it("should prepare graphql schema & call handler", async () => { - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); // Test `/` alias svc.prepareGraphQLSchema = jest.fn(); @@ -111,7 +111,7 @@ describe("Test Service", () => { const fakeReq = { req: 1 }; const fakeRes = { res: 1 }; - const res = svc.settings.routes[0].aliases[ + const res = await svc.settings.routes[0].aliases[ "GET /.well-known/apollo/server-health" ].call(svc, fakeReq, fakeRes); @@ -124,7 +124,7 @@ describe("Test Service", () => { }); it("should call sendError if error occured", async () => { - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); const err = new Error("Something happened"); svc.sendResponse = jest.fn(); @@ -135,7 +135,7 @@ describe("Test Service", () => { const fakeReq = { req: 1 }; const fakeRes = { res: 1 }; - const res = svc.settings.routes[0].aliases[ + const res = await svc.settings.routes[0].aliases[ "GET /.well-known/apollo/server-health" ].call(svc, fakeReq, fakeRes); @@ -160,7 +160,7 @@ describe("Test Service", () => { }); it("should register a route with custom options", async () => { - const { broker, svc, stop } = await startService({ + const { svc, stop } = await startService({ routeOptions: { path: "/apollo-server", @@ -314,7 +314,7 @@ describe("Test Service", () => { describe("Test methods", () => { describe("Test 'invalidateGraphQLSchema'", () => { it("should create the 'graphql' action", async () => { - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); svc.shouldUpdateGraphqlSchema = false; @@ -395,7 +395,7 @@ describe("Test Service", () => { it("should call actionResolvers", async () => { const { svc, stop } = await startService(); - svc.createActionResolver = jest.fn((name, r) => jest.fn()); + svc.createActionResolver = jest.fn(() => jest.fn()); const resolvers = { author: { @@ -1030,7 +1030,7 @@ describe("Test Service", () => { describe("Test 'generateGraphQLSchema'", () => { it("should create an empty schema", async () => { makeExecutableSchema.mockImplementation(() => "generated-schema"); - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); const res = svc.generateGraphQLSchema([]); expect(res).toBe("generated-schema"); @@ -1048,7 +1048,7 @@ describe("Test Service", () => { it("should create a schema with schemaDirectives", async () => { makeExecutableSchema.mockClear(); const UniqueIdDirective = jest.fn(); - const { broker, svc, stop } = await startService({ + const { svc, stop } = await startService({ schemaDirectives: { uid: UniqueIdDirective, }, @@ -1081,7 +1081,7 @@ describe("Test Service", () => { }, }, }; - const { broker, svc, stop } = await startService({ + const { svc, stop } = await startService({ typeDefs: ` scalar Date `, @@ -1310,7 +1310,7 @@ describe("Test Service", () => { makeExecutableSchema.mockImplementation(() => { throw new Error("Something is wrong"); }); - const { broker, svc, stop } = await startService(); + const { svc, stop } = await startService(); expect(() => svc.generateGraphQLSchema([])).toThrow(Errors.MoleculerServerError);