Skip to content

Commit

Permalink
fix: startup for services created with broker.createService
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Ermer committed Aug 2, 2023
1 parent cdd4933 commit f5fb201
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 30 deletions.
28 changes: 17 additions & 11 deletions src/service-broker.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ class ServiceBroker {
// Broker started flag
this.started = false;

/** @type {Boolean} Broker is starting inital services flag*/
this.servicesStarted = false;

/** @type {Boolean} Broker stopping flag*/
this.stopping = false;

Expand Down Expand Up @@ -463,16 +466,19 @@ class ServiceBroker {
})
.then(() => {
// Call service `started` handlers
return this.Promise.all(this.services.map(svc => svc._start.call(svc))).catch(
err => {
/* istanbul ignore next */
this.logger.error("Unable to start all services.", err);
throw err;
}
);
const startingServices = this.services.map(svc => svc._start.call(svc));
// Set servicesStarted, so new services created from now on will be started when registered
this.servicesStarted = true;
// Wait for services `started` handlers
return this.Promise.all(startingServices).catch(err => {
/* istanbul ignore next */
this.logger.error("Unable to start all services.", err);
throw err;
});
})
.then(() => {
this.started = true;
this.servicesStarted = false;
this.metrics.set(METRIC.MOLECULER_BROKER_STARTED, 1);
this.broadcastLocal("$broker.started");
})
Expand Down Expand Up @@ -784,15 +790,15 @@ class ServiceBroker {
svc = new schema(this);

// If broker is started, call the started lifecycle event of service
if (this.started) this._restartService(svc);
if (this.started || this.servicesStarted) this._restartService(svc);
} else if (utils.isFunction(schema)) {
// Function
svc = schema(this);
if (!utils.isInheritedClass(svc, this.ServiceFactory)) {
svc = this.createService(svc);
} else {
// If broker is started, call the started lifecycle event of service
if (this.started) this._restartService(svc);
if (this.started || this.servicesStarted) this._restartService(svc);
}
} else if (schema) {
// Schema object
Expand Down Expand Up @@ -834,8 +840,8 @@ class ServiceBroker {
service = new this.ServiceFactory(this, schema, schemaMods);
}

// If broker has started yet, call the started lifecycle event of service
if (this.started) this._restartService(service);
// If broker has began to start its initial services yet, call the started lifecycle event of service
if (this.started || this.servicesStarted) this._restartService(service);

return service;
}
Expand Down
96 changes: 77 additions & 19 deletions test/unit/service-broker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,20 +520,47 @@ describe("Test ServiceBroker constructor", () => {

describe("Test broker.start", () => {
describe("without transporter", () => {
const schema = {
name: "test",
started: jest.fn()
};

const optStarted = jest.fn();
let schema;
let optStarted;
let broker;
let svc;

beforeEach(() => {
schema = {
name: "test",
started: jest.fn(() => Promise.resolve())
};

optStarted = jest.fn();
broker = new ServiceBroker({
logger: false,
transporter: null,
started: optStarted
});

const broker = new ServiceBroker({
logger: false,
transporter: null,
started: optStarted
svc = broker.createService(schema);
});

const svc = broker.createService(schema);
it("should call started of services, created whilst starting an initial service", async () => {
const shouldBeCalled = jest.fn();
const serviceStartingOthers = broker.createService({
name: "test",
started: () => {
broker.createService({
name: "test",
started: shouldBeCalled
});
broker.waitForServices("test");
// do something
}
});
broker.broadcastLocal = jest.fn();
broker.metrics.set = jest.fn();
broker.callMiddlewareHook = jest.fn();
broker.registry.regenerateLocalRawInfo = jest.fn();
await broker.start();
expect(shouldBeCalled).toHaveBeenCalledTimes(1);
});

it("should call started of services", async () => {
broker.services.forEach(svc => (svc._start = jest.fn()));
Expand Down Expand Up @@ -570,22 +597,53 @@ describe("Test broker.start", () => {
started: jest.fn(() => Promise.resolve())
};

const optStarted = jest.fn();
const broker = new ServiceBroker({
logger: false,
transporter: "Fake",
started: optStarted
it("should call started of services, created whilst starting an initial service", async () => {
const optStarted = jest.fn();
const broker = new ServiceBroker({
logger: false,
transporter: "Fake",
started: optStarted
});
broker.transit.connect = jest.fn(() => Promise.resolve());
broker.transit.ready = jest.fn(() => Promise.resolve());
broker.transit.connect = jest.fn(() => Promise.resolve());
broker.transit.ready = jest.fn(() => Promise.resolve());
broker.broadcastLocal = jest.fn();
broker.metrics.set = jest.fn();
broker.callMiddlewareHook = jest.fn();
broker.createService(schema);
const shouldBeCalled = jest.fn();
broker.createService({
name: "test2",
started: () => {
broker.createService({
name: "test3",
started: shouldBeCalled
});
broker.waitForServices("test");
// do something
}
});
await broker.start();
expect(shouldBeCalled).toHaveBeenCalledTimes(1);
});

const svc = broker.createService(schema);

it("should call started of services", async () => {
broker.services.forEach(svc => (svc._start = jest.fn()));
const optStarted = jest.fn();
const broker = new ServiceBroker({
logger: false,
transporter: "Fake",
started: optStarted
});
const svc = broker.createService(schema);
broker.transit.connect = jest.fn(() => Promise.resolve());
broker.transit.ready = jest.fn(() => Promise.resolve());
broker.transit.connect = jest.fn(() => Promise.resolve());
broker.transit.ready = jest.fn(() => Promise.resolve());
broker.broadcastLocal = jest.fn();
broker.metrics.set = jest.fn();
broker.callMiddlewareHook = jest.fn();
broker.services.forEach(svc => (svc._start = jest.fn()));
//broker.scope.enable = jest.fn();
//broker.tracer.restartScope = jest.fn();

Expand Down

0 comments on commit f5fb201

Please sign in to comment.