@appolo/bus
Version:
appolo bus module
153 lines (107 loc) • 4.33 kB
text/typescript
import {define, inject, Injector, singleton} from "@appolo/inject";
import {IHandler} from "../common/interfaces";
import {HandlersManager} from "../handlers/handlersManager";
import {RepliesManager} from "../handlers/repliesManager";
import {TopologyManager} from "../topology/topologyManager";
import {ILogger} from "@appolo/logger/index";
import {Promises} from "@appolo/utils";
import {BusProvider} from "../bus/busProvider";
import {RequestError} from "../common/requestError";
import {Rabbit, Message, Handler} from "appolo-rabbit";
export class MessageManager {
protected client: Rabbit;
protected injector: Injector;
private handlersManager: HandlersManager;
private repliesManager: RepliesManager;
private topologyManager: TopologyManager;
protected logger: ILogger;
protected busProvider: BusProvider;
private _handler: Handler;
private _handlerRequest: Handler;
private _initialized = false;
public async initialize() {
this._handler = this.client.handle({
type: "#",
handler: msg => this._handleMessage(msg),
queue: this.topologyManager.getDefaultQueueName()
});
this._handlerRequest = this.client.handle({
type: "#",
handler: msg => this._handleRequestMessage(msg),
queue: this.topologyManager.getDefaultRequestQueueName()
});
await this.client.subscribe();
let handlers = this.handlersManager.getHandlersProperties();
if (handlers.length) {
this.logger.info(`bus handlers subscription ${handlers.map((item) => item.eventName).join(",")}`);
}
let replyHandlers = this.repliesManager.getHandlersProperties()
if (replyHandlers.length) {
this.logger.info(`bus reply subscription ${replyHandlers.map((item) => item.eventName).join(",")}`);
}
this._initialized = true;
}
private async _handleRequestMessage(msg: Message<any>) {
let replies = this.repliesManager.getHandlers(msg.type, msg.queue, msg.fields.exchange, msg.fields.routingKey);
if (replies.length) {
await this._callReply(msg, replies[0]);
}
msg.ack();
}
private async _handleMessage(msg: Message<any>) {
let handlers = this.handlersManager.getHandlers(msg.type, msg.queue, msg.fields.exchange, msg.fields.routingKey);
if (handlers.length) {
await Promises.map(handlers || [], handler => this._callHandler(msg, handler));
}
msg.ack();
}
private async _callHandler(msg: Message<any>, handler: IHandler) {
try {
let instance = this._getHandlerInjector(handler).get(handler.define.definition.id);
if (handler.retry) {
msg.retry = handler.retry
}
await instance[handler.propertyKey](msg);
if (!msg.isAcked) {
msg.ack();
}
} catch (e) {
this.logger.error(`failed to handle message ${msg.type}`, {err: e, msg: msg.body});
if (!msg.isAcked) {
msg.nack();
}
}
}
private _getHandlerInjector(handler: IHandler): Injector {
let def = handler.define.definition,
injector = def.injector && def.injector.hasDefinition(def.id)
? def.injector
: this.injector.parent;
return injector;
}
private async _callReply(msg: Message<any>, handler: IHandler) {
try {
let instance = this._getHandlerInjector(handler).get(handler.define.definition.id);
let data = await instance[handler.propertyKey](msg);
if (!msg.isAcked) {
msg.replyResolve(data)
}
} catch (e) {
if (!msg.isAcked) {
msg.replyReject(e)
}
}
}
public async clean() {
if (this._initialized) {
await this.client.unSubscribe();
this._handler.remove();
this._handlerRequest.remove();
}
this.repliesManager.clean();
this.handlersManager.clean();
this._handler = null;
}
}