UNPKG

matchmaker-redis

Version:

A module that helps users join some kind of social event such as a multiplayer game.

104 lines (86 loc) 3.04 kB
const _ = require('lodash') const shortid = require('shortid') const installLuaScripts = require('./lib/lua-scipts') const pendingKey = 'events/pending' const activeKey = 'events/active' var redis function createEvent(args) { const userId = args.userId const userAlias = args.userAlias if (_.isUndefined(userId) || _.isUndefined(userAlias)) return Promise.reject(new Error('user required')) const capacity = Math.max(2, parseInt(args.capacity, 10) || 0) const whitelist = _.uniq(args.whitelist || []) const blacklist = _.uniq(args.blacklist || []) if (_.indexOf(whitelist, userId) !== -1 || _.indexOf(blacklist, userId) !== -1 || !_.isEmpty(_.intersection(whitelist, blacklist))) return Promise.reject(new Error('invalid whitelist/blacklist')) const perUserTimeoutSec = Math.max(1, parseInt(args.perUserTimeoutSec, 10) || 30) const params = args.params || '' if (!_.isString(params)) return Promise.reject(new Error('invalid params')) const event = { id: shortid(), capacity, params: _.trim(params), whitelist, blacklist, userIds: [userId], aliases: [userAlias] } return redis.createEvent(`events/${event.id}`, pendingKey, JSON.stringify(event)).then(() => { const timeout = event.capacity * perUserTimeoutSec * 1000 setTimeout(function autoCancelEvent() { cancelEvent(userId, event.id).catch(err => { // Just eat this error since it's an automatic cancellation or expiration; // not a user action. // // console.warn('cannot auto-cancel event %s: %s', event.id, err.message) }) }, timeout) return event }) } function autojoinEvent(args) { const userId = args.userId const userAlias = args.userAlias if (_.isUndefined(userId) || _.isUndefined(userAlias)) return Promise.reject(new Error('user required')) const capacity = Math.max(2, parseInt(args.capacity, 10) || 0) const params = args.params || '' if (!_.isString(params)) return Promise.reject(new Error('invalid params')) return redis.autojoinEvent( pendingKey, activeKey, userId, userAlias, capacity, params, _.now() / 1000 | 0) .then(json => !json ? null : JSON.parse(json)) } function cancelEvent(userId, eventId) { return redis.cancelEvent(`events/${eventId}`, pendingKey, userId) } function getEventsFor(userId) { return redis.getPendingEventsFor(pendingKey, userId).then(function (json) { this.pendingEvents = JSON.parse(json) return redis.getActiveEventsFor(activeKey, userId) }).then(function (json) { return { pending: this.pendingEvents, active: JSON.parse(json) } }) } function joinEvent(userId, userAlias, eventId) { return redis.joinEvent(`events/${eventId}`, pendingKey, activeKey, userId, userAlias, _.now() / 1000 | 0).then(JSON.parse) } module.exports = function (redisClient) { redis = redisClient installLuaScripts(redisClient) return {createEvent, autojoinEvent, getEventsFor, joinEvent, cancelEvent} }