UNPKG

@betit/orion

Version:

Pluggable microservice framework

171 lines (170 loc) 4.61 kB
"use strict"; const nats = require('nats'); const utils_1 = require('../utils'); const debug = utils_1.debugLog('orion:transport:nats'); /** * NATS transport. */ class NatsTransport { /** * Create new NATS transport. */ constructor(options) { this.options = options; this.options = Object.assign({ url: process.env.NATS || 'nats://localhost:4222', encoding: 'binary' }, options); this.client = nats.connect(this.options); this.client.on('error', function (e) { debug(e); process.exit(); }); this.heartbeat(); } /** * NATS heartbeat check based on * https://github.com/nats-io/node-nats/issues/173 */ heartbeat() { let timeout = null; setInterval(() => { timeout = setTimeout(() => { timeout = null; }, 500); this.listen(() => { if (timeout) { clearTimeout(timeout); timeout = null; } }); }, 1000); } /** * Transport listen. */ listen(callback) { try { this.client.flush((err) => { if (err) { throw err; } if (callback && callback instanceof Function) { callback(); } }); } catch (e) { if (e.code === nats.CONN_CLOSED && this.closeHandler) { this.closeHandler(); } throw e; } } /** * Publish to a topic. */ publish(topic, message) { try { this.client.publish(topic, message); } catch (e) { if (e.code === nats.CONN_CLOSED && this.closeHandler) { this.closeHandler(); } throw e; } } /** * Subscribe to a topic. */ subscribe(topic, group, callback) { try { return this.client.subscribe(topic, { queue: group }, callback); } catch (e) { if (e.code === nats.CONN_CLOSED && this.closeHandler) { this.closeHandler(); } throw e; } } /** * Unsubscribe from a topic. */ unsubscribe(sid, max) { try { this.client.unsubscribe(sid, max); } catch (e) { if (e.code === nats.CONN_CLOSED && this.closeHandler) { this.closeHandler(); } throw e; } } /** * Transport handle. */ handle(route, group, callback) { try { debug('register handler:', route); this.client.subscribe(route, { queue: group }, (req, replyTo) => { debug('incoming request:', req, replyTo); callback(req, res => { debug('sending response:', replyTo, res); this.client.publish(replyTo, res); }); }); } catch (e) { if (e.code === nats.CONN_CLOSED && this.closeHandler) { this.closeHandler(); } throw e; } } /** * Client request. * Nats client implements this pattern out of the box. * Publish a request with an implicit inbox listener as the response. * This should be treated as a subscription. */ request(route, payload, callback, timeout = 1000) { try { debug('sending request:', route); const sid = this.client.request(route, payload, { max: 1 }, response => { debug('got response:', response); callback(response); }); this.client.timeout(sid, timeout, 1, () => { debug('request timeout:', route); callback(new Error(`Transport timeout: ${route}`)); }); } catch (e) { if (e.code === nats.CONN_CLOSED && this.closeHandler) { this.closeHandler(); } throw e; } } /** * Close connection. */ close() { this.client.close(); } /** * Connection closed handler * @param {Function} callback */ onClose(callback) { if (callback) { this.closeHandler = callback; this.client.on('close', callback); } } } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = NatsTransport;