UNPKG

@colyseus/redis-driver

Version:

<div align="center"> <a href="https://github.com/colyseus/colyseus"> <img src="media/logo.svg?raw=true" width="60%" height="300" /> </a> <br> <br> <a href="https://npmjs.com/package/colyseus"> <img src="https://img.shields.io/npm/dm/coly

96 lines (95 loc) 3.26 kB
// packages/drivers/redis-driver/src/RedisDriver.ts import Redis, { Cluster } from "ioredis"; import { debugMatchMaking } from "@colyseus/core"; import { Query } from "./Query.mjs"; import { RoomData } from "./RoomData.mjs"; var ROOMCACHES_KEY = "roomcaches"; var RedisDriver = class { constructor(options, clusterOptions) { this._roomCacheRequestByName = {}; this._client = Array.isArray(options) ? new Cluster(options, clusterOptions) : new Redis(options); } createInstance(initialValues = {}) { return new RoomData(initialValues, this._client); } async has(roomId) { return await this._client.hexists(ROOMCACHES_KEY, roomId) === 1; } async query(conditions, sortOptions) { const rooms = await this.getRooms(); return rooms.filter((room) => { if (!room.roomId) { return false; } for (const field in conditions) { if (conditions.hasOwnProperty(field) && room[field] !== conditions[field]) { return false; } } return true; }); } async cleanup(processId) { const cachedRooms = await this.query({ processId }); debugMatchMaking("removing stale rooms by processId %s (%s rooms found)", processId, cachedRooms.length); const itemsPerCommand = 500; for (let i = 0; i < cachedRooms.length; i += itemsPerCommand) { await this._client.hdel(ROOMCACHES_KEY, ...cachedRooms.slice(i, i + itemsPerCommand).map((room) => room.roomId)); } } findOne(conditions, sortOptions) { if (typeof conditions.roomId !== "undefined") { return new Promise((resolve, reject) => { this._client.hget(ROOMCACHES_KEY, conditions.roomId).then((roomcache) => { if (roomcache) { resolve(new RoomData(JSON.parse(roomcache), this._client)); } else { resolve(void 0); } }).catch(reject); }); } else { const query = new Query(this.getRooms(conditions["name"]), conditions); if (sortOptions) { query.sort(sortOptions); } return query; } } getRooms(roomName) { if (this._roomCacheRequestByName[roomName] !== void 0) { return this._roomCacheRequestByName[roomName]; } const roomCacheRequest = this._concurrentRoomCacheRequest || this._client.hgetall(ROOMCACHES_KEY); this._concurrentRoomCacheRequest = roomCacheRequest; this._roomCacheRequestByName[roomName] = roomCacheRequest.then((result) => { this._concurrentRoomCacheRequest = void 0; delete this._roomCacheRequestByName[roomName]; let roomcaches = Object.entries(result ?? []); if (roomName !== void 0) { const roomNameField = `"name":"${roomName}"`; roomcaches = roomcaches.filter(([, roomcache]) => roomcache.includes(roomNameField)); } return roomcaches.map( // TODO: probably no need to instantiate RoomData here. ([, roomcache]) => new RoomData(JSON.parse(roomcache), this._client) ); }); return this._roomCacheRequestByName[roomName]; } async shutdown() { await this._client.quit(); } // // only relevant for the test-suite. // not used during runtime. // clear() { this._client.del(ROOMCACHES_KEY); } }; export { RedisDriver };