UNPKG

pomelo-upgrade

Version:
162 lines (144 loc) 3.87 kB
'use strict'; const fs = require('fs'); const utils = require('../../util/utils'); const Loader = require('pomelo-loader-upgrade'); const pathUtil = require('../../util/pathUtil'); const logger = require('pomelo-logger-upgrade').getLogger('pomelo', __filename); const forwardLogger = require('pomelo-logger-upgrade').getLogger('forward_log', __filename); /** * Handler service. * Dispatch request to the relative handler. * * @param {object} app current application context */ const Service = function(app, opts) { this.app = app; this.handlerMap = {}; if (opts.reloadHandlers) { watchHandlers(app, this.handlerMap); } this.enableForwardLog = opts.enableForwardLog || false; }; module.exports = Service; Service.prototype.name = 'handler'; /** * Handler the request. */ Service.prototype.handle = function(routeRecord, msg, session, cb) { // the request should be processed by current server const handler = this.getHandler(routeRecord); if (!handler) { logger.error('[handleManager]: fail to find handler for %j', msg.__route__); utils.invokeCallback(cb, new Error(`fail to find handler for ${msg.__route__}`)); return; } const start = Date.now(); const callback = (err, resp, opts) => { if (this.enableForwardLog) { const log = { route : msg.__route__, args : msg, time : utils.format(new Date(start)), timeUsed : new Date() - start }; forwardLogger.info(JSON.stringify(log)); } // resp = getResp(arguments); utils.invokeCallback(cb, err, resp, opts); }; const method = routeRecord.method; if (!Array.isArray(msg)) { handler[method](msg, session, callback); } else { msg.push(session); msg.push(callback); handler[method](...msg); } }; /** * Get handler instance by routeRecord. * * @param {object} routeRecord route record parsed from route string * @return {object} handler instance if any matches or null for match fail */ Service.prototype.getHandler = function(routeRecord) { const serverType = routeRecord.serverType; if (!this.handlerMap[serverType]) { loadHandlers(this.app, serverType, this.handlerMap); } const handlers = this.handlerMap[serverType] || {}; const handler = handlers[routeRecord.handler]; if (!handler) { logger.warn('could not find handler for routeRecord: %j', routeRecord); return null; } if (typeof handler[routeRecord.method] !== 'function') { logger.warn('could not find the method %s in handler: %s', routeRecord.method, routeRecord.handler); return null; } return handler; }; /** * Load handlers from current application */ const loadHandlers = function(app, serverType, handlerMap) { const p = pathUtil.getHandlerPath(app.getBase(), serverType); if (p) { handlerMap[serverType] = Loader.load(p, app); } }; const watchHandlers = function(app, handlerMap) { const p = pathUtil.getHandlerPath(app.getBase(), app.serverType); if (p) { fs.watch(p, function(event, name) { if (event === 'change') { handlerMap[app.serverType] = Loader.load(p, app); } }); } }; const getResp = function(args) { const len = args.length; if (len == 1) { return []; } if (len == 2) { return [args[1]]; } if (len == 3) { return [args[1], args[2]]; } if (len == 4) { return [args[1], args[2], args[3]]; } const r = new Array(len); for (let i = 1; i < len; i++) { r[i] = args[i]; } return r; };