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

8 lines (7 loc) 6.89 kB
{ "version": 3, "sources": ["../src/RedisDriver.ts"], "sourcesContent": ["import Redis, { Cluster, ClusterNode, ClusterOptions, RedisOptions } from 'ioredis';\n\nimport {\n IRoomCache,\n MatchMakerDriver,\n SortOptions,\n debugMatchMaking,\n} from '@colyseus/core';\n\nimport { Query } from './Query.js';\nimport { RoomData } from './RoomData.js';\n\nconst ROOMCACHES_KEY = 'roomcaches';\n\nexport class RedisDriver implements MatchMakerDriver {\n private readonly _client: Redis | Cluster;\n\n constructor(options?: number | string | RedisOptions | ClusterNode[], clusterOptions?: ClusterOptions) {\n this._client = (Array.isArray(options))\n ? new Cluster(options, clusterOptions)\n : new Redis(options as RedisOptions);\n }\n\n public createInstance(initialValues: Partial<IRoomCache> = {}) {\n return new RoomData(initialValues, this._client);\n }\n\n public async has(roomId: string) {\n return await this._client.hexists(ROOMCACHES_KEY, roomId) === 1;\n }\n\n public async query(conditions: Partial<IRoomCache>, sortOptions?: SortOptions) {\n const rooms = await this.getRooms();\n return rooms.filter((room) => {\n if (!room.roomId) {\n return false;\n }\n\n for (const field in conditions) {\n if (\n conditions.hasOwnProperty(field) &&\n room[field] !== conditions[field]\n ) {\n return false;\n }\n }\n return true;\n });\n }\n\n public async cleanup(processId: string) {\n const cachedRooms = await this.query({ processId });\n debugMatchMaking(\"removing stale rooms by processId %s (%s rooms found)\", processId, cachedRooms.length);\n\n const itemsPerCommand = 500;\n\n // remove rooms in batches of 500\n for (let i = 0; i < cachedRooms.length; i += itemsPerCommand) {\n await this._client.hdel(ROOMCACHES_KEY, ...cachedRooms.slice(i, i + itemsPerCommand).map((room) => room.roomId));\n }\n }\n\n public findOne(conditions: Partial<IRoomCache>, sortOptions?: SortOptions): Promise<RoomData> {\n if (typeof conditions.roomId !== 'undefined') {\n // get room by roomId\n\n //\n // TODO: refactor driver APIs.\n // the API here is legacy from MongooseDriver which made sense on versions <= 0.14.0\n //\n\n // @ts-ignore\n return new Promise<IRoomCache>((resolve, reject) => {\n this._client.hget(ROOMCACHES_KEY, conditions.roomId).then((roomcache) => {\n if (roomcache) {\n resolve(new RoomData(JSON.parse(roomcache), this._client));\n } else {\n resolve(undefined);\n }\n }).catch(reject);\n });\n\n } else {\n // filter list by other conditions\n const query = new Query<RoomData>(this.getRooms(conditions['name']), conditions);\n\n if (sortOptions) {\n query.sort(sortOptions);\n }\n\n return query as any as Promise<RoomData>;\n }\n }\n\n // gets recent room caches w/o making multiple simultaneous reads to REDIS\n private _concurrentRoomCacheRequest?: Promise<Record<string, string>>;\n private _roomCacheRequestByName: {[roomName: string]: Promise<RoomData[]>} = {};\n private getRooms(roomName?: string) {\n // if there's a shared request, return it\n if (this._roomCacheRequestByName[roomName] !== undefined) {\n return this._roomCacheRequestByName[roomName];\n }\n\n const roomCacheRequest = this._concurrentRoomCacheRequest || this._client.hgetall(ROOMCACHES_KEY);\n this._concurrentRoomCacheRequest = roomCacheRequest;\n\n this._roomCacheRequestByName[roomName] = roomCacheRequest.then((result) => {\n // clear shared promises so we can read it again\n this._concurrentRoomCacheRequest = undefined;\n delete this._roomCacheRequestByName[roomName];\n\n let roomcaches = Object.entries(result ?? []);\n\n //\n // micro optimization:\n // filter rooms by name before parsing JSON\n //\n if (roomName !== undefined) {\n const roomNameField = `\"name\":\"${roomName}\"`;\n roomcaches = roomcaches.filter(([, roomcache]) => roomcache.includes(roomNameField));\n }\n\n return roomcaches.map(\n // TODO: probably no need to instantiate RoomData here.\n ([, roomcache]) => new RoomData(JSON.parse(roomcache), this._client)\n );\n });\n\n return this._roomCacheRequestByName[roomName];\n }\n\n public async shutdown() {\n await this._client.quit();\n }\n\n //\n // only relevant for the test-suite.\n // not used during runtime.\n //\n public clear() {\n this._client.del(ROOMCACHES_KEY);\n }\n\n}\n"], "mappings": "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", "names": [] }