-
Notifications
You must be signed in to change notification settings - Fork 568
/
Copy pathr-gamemanager.coffee
124 lines (114 loc) · 3.78 KB
/
r-gamemanager.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Promise = require 'bluebird'
Logger = require '../../app/common/logger.coffee'
config = require '../../config/config.js'
env = config.get("env")
ttl = config.get("redis.ttl")
generatePushID = require '../../app/common/generate_push_id'
zlib = Promise.promisifyAll(require 'zlib')
# Helper returns the Game Data Redis key prefix
keyPrefix = () ->
return "#{env}:games:"
# Helper returns the Game Mouse/UI Event Data Redis key prefix
keyPrefixForMouseUIData = () ->
return "#{env}:games_mouse_ui_data:"
###*
# Class 'RedisGameManager'
# Manages storage of games in Redis
# Serialized games are stored by incrementing id
# ttl sets the expiration time of keys, defaults to 72 hours
###
class RedisGameManager
###*
# Constructor
# @param {Object} redis, a promisified redis connection
###
constructor: (redis, opts = {}) ->
# TODO: add check to ensure Redis client is already promisified
@redis = redis
return
###*
# Generate a unique id for the game using atomic increment
# @param {Function|optional} callback
# @return {Promise}
###
generateGameId: (callback) ->
p = new Promise (resolve,reject)->
resolve(generatePushID())
return p.nodeify(callback)
###*
# Save *serialized* game session data to redis
# @param {String} the game id to be used as the key
# @param {Object} the game data *after* serializing
# @param {Function|optional} callback
# @return {Promise}
###
saveGameSession: (gameId, serializedGameData, callback) ->
Logger.module("REDIS").debug "saveGameSession() -> saving GameSession #{gameId}"
gameKey = keyPrefix() + gameId
return zlib.gzipAsync(serializedGameData)
.then (gzipGameData) =>
# gzipGameData is a buffer
multi = @redis.multi() # start a multi command
multi.set(gameKey, gzipGameData)
multi.expire(gameKey, ttl) # mark to expire at ttl
return multi.execAsync()
.nodeify(callback)
###*
# Load *serialized* game session data from redis
# @param {String} the game id to be used as the key
# @param {Function|optional} callback
# @return {Promise}
###
loadGameSession: (gameId, callback) ->
Logger.module("REDIS").debug "loadGameSession() -> loading GameSession #{gameId}"
gameKey = keyPrefix() + gameId
# Must pass a new Buffer(key) to get back a buffer object
return @redis.getAsync(new Buffer(gameKey))
.then (buffer) ->
if buffer
return zlib.gunzipAsync(buffer)
else
# just return the empty buffer (null)
return buffer
.nodeify(callback)
###*
# Save *serialized* game mouse and ui data to redis
# @param {String} the game id to be used as the key
# @param {Object} the data *after* serializing
# @param {Function|optional} callback
# @return {Promise}
###
saveGameMouseUIData: (gameId, serializedData, callback) ->
Logger.module("REDIS").debug "saveGameMouseUIData() -> saving data for game #{gameId}"
key = keyPrefixForMouseUIData() + gameId
return zlib.gzipAsync(serializedData)
.then (gzipMouseData) =>
# gzipMouseData is a buffer
multi = @redis.multi() # start a multi command
multi.set(key, gzipMouseData)
multi.expire(key, ttl) # mark to expire at ttl
return multi.execAsync()
.nodeify(callback)
###*
# Load *serialized* game mouse and ui data from redis
# @param {String} the game id to be used as the key
# @param {Function|optional} callback
# @return {Promise}
###
loadGameMouseUIData: (gameId, callback) ->
Logger.module("REDIS").debug "loadGameMouseUIData() -> loading data for game #{gameId}"
key = keyPrefixForMouseUIData() + gameId
return @redis.getAsync(new Buffer(key))
.then (buffer) ->
if buffer
return zlib.gunzipAsync(buffer)
else
# just return the empty buffer (null)
return buffer
.nodeify(callback)
###*
# Export a factory
###
module.exports = exports = (redis, opts) ->
GameManager = new RedisGameManager(redis, opts)
return GameManager