UNPKG

thinknode

Version:

A fast, flexible and all-in-one web framework for node.js.

269 lines (216 loc) 10.7 kB
'use strict'; exports.__esModule = true; var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * 基于redis的简单队列 * 支持订阅sub,发布pub * @author richen * @copyright Copyright (c) 2016 - <richenlin(at)gmail.com> * @license MIT * @version 2016/11/2 */ var _class = function (_THINK$Base) { (0, _inherits3.default)(_class, _THINK$Base); function _class() { (0, _classCallCheck3.default)(this, _class); return (0, _possibleConstructorReturn3.default)(this, _THINK$Base.apply(this, arguments)); } _class.prototype.init = function init(channel, options) { this.channel = channel || 'queue'; this.options = { redis_host: options.redis_host || '127.0.0.1', redis_port: options.redis_port || 6379, redis_db: options.redis_db || '1', redis_password: options.redis_password || '', redis_timeout: null }; this.prefix = 'THINKQUEUE'; }; _class.prototype.connect = function () { var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2() { var key, self; return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: key = THINK.hash(this.options.redis_host + '_' + this.channel); !THINK_CACHES.INSTANCES.REDISQUEUE && (THINK_CACHES.INSTANCES.REDISQUEUE = {}); if (!THINK_CACHES.INSTANCES.REDISQUEUE[key]) { _context2.next = 4; break; } return _context2.abrupt('return', _promise2.default.resolve(THINK_CACHES.INSTANCES.REDISQUEUE[key])); case 4: self = this; return _context2.abrupt('return', THINK.await(key, (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee() { var pub, sub; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: THINK_CACHES.INSTANCES.REDISQUEUE[key] = {}; pub = THINK.adapter('RedisSocket', self.options); sub = THINK.adapter('RedisSocket', self.options); THINK_CACHES.INSTANCES.REDISQUEUE[key].INS = pub; THINK_CACHES.INSTANCES.REDISQUEUE[key].INS.QUEUE = {}; _context.next = 7; return pub.connect(); case 7: THINK_CACHES.INSTANCES.REDISQUEUE[key].PUB = pub.handle; _context.next = 10; return sub.connect(); case 10: THINK_CACHES.INSTANCES.REDISQUEUE[key].SUB = sub.handle; return _context.abrupt('return', THINK_CACHES.INSTANCES.REDISQUEUE[key]); case 12: case 'end': return _context.stop(); } } }, _callee, this); })))); case 6: case 'end': return _context2.stop(); } } }, _callee2, this); })); function connect() { return _ref.apply(this, arguments); } return connect; }(); /** * 发布 * @param data */ _class.prototype.pub = function () { var _ref3 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(data) { var key, handle; return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: key = this.prefix + '_' + this.channel, handle = void 0; return _context3.abrupt('return', this.connect(this.channel).then(function (cls) { handle = cls; return THINK.await(key, function () { return handle.INS.wrap('lrange', [key, 0, -1]).then(function (list) { //队列中存在未处理完的任务 var ps = []; list.forEach(function (item) { ps.push(handle.PUB.publish(key, item)); }); return _promise2.default.all(ps); }); }); }).then(function () { //非标量序列化 if (!THINK.isScalar(data)) { data = (0, _stringify2.default)(data); } //压入队列 return handle.INS.wrap('rpush', [key, data]); }).then(function () { return handle.PUB.publish(key, data); })); case 2: case 'end': return _context3.stop(); } } }, _callee3, this); })); function pub(_x) { return _ref3.apply(this, arguments); } return pub; }(); /** * 取消发布 * @returns {Promise.<TResult>} */ _class.prototype.unpub = function unpub() { return this.connect(this.channel).then(function (cls) { return cls.PUB.quit(); }); }; /** * 订阅 * @param handles * @returns {Promise.<TResult>} */ _class.prototype.sub = function () { var _ref4 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(handles) { var _this2 = this; var key, handle; return _regenerator2.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: key = this.prefix + '_' + this.channel, handle = void 0; return _context4.abrupt('return', this.connect(this.channel).then(function (cls) { handle = cls; //防止多次订阅 if (!handle.INS.QUEUE[_this2.channel]) { handle.INS.QUEUE[_this2.channel] = 1; handle.SUB.subscribe(key); //订阅处理 handle.SUB.on('message', function (channel, msg) { return handle.INS.wrap('lpop', [key]).then(function (value) { //外部处理函数托管 return handles(value, msg); }); // .catch(err => { // return handle.INS.wrap('rpush', [key, data]); //}); }); } return _promise2.default.resolve(); // return handle.INS.wrap('lrange', [key, 0, -1]); // }).then(list => { // //队列中存在未处理完的任务 // let ps = []; // list.forEach(item => { // ps.push(func(key, item, arg)); // }); // return Promise.all(ps); })); case 2: case 'end': return _context4.stop(); } } }, _callee4, this); })); function sub(_x2) { return _ref4.apply(this, arguments); } return sub; }(); /** * 取消订阅 */ _class.prototype.ubsub = function ubsub() { return this.connect(this.channel).then(function (cls) { return cls.SUB.quit(); }); }; return _class; }(THINK.Base); exports.default = _class;