Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / socket.io / lib / stores / redis.js
1
2 /*!
3  * socket.io-node
4  * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
5  * MIT Licensed
6  */
7
8 /**
9  * Module dependencies.
10  */
11
12 var crypto = require('crypto')
13   , Store = require('../store')
14   , assert = require('assert');
15
16 /**
17  * Exports the constructor.
18  */
19
20 exports = module.exports = Redis;
21 Redis.Client = Client;
22
23 /**
24  * Redis store.
25  * Options:
26  *     - nodeId (fn) gets an id that uniquely identifies this node
27  *     - redis (fn) redis constructor, defaults to redis
28  *     - redisPub (object) options to pass to the pub redis client
29  *     - redisSub (object) options to pass to the sub redis client
30  *     - redisClient (object) options to pass to the general redis client
31  *     - pack (fn) custom packing, defaults to JSON or msgpack if installed
32  *     - unpack (fn) custom packing, defaults to JSON or msgpack if installed
33  *
34  * @api public
35  */
36
37 function Redis (opts) {
38   opts = opts || {};
39
40   // node id to uniquely identify this node
41   var nodeId = opts.nodeId || function () {
42     // by default, we generate a random id 
43     return Math.abs(Math.random() * Math.random() * Date.now() | 0);
44   };
45
46   this.nodeId = nodeId();
47
48   // packing / unpacking mechanism
49   if (opts.pack) {
50     this.pack = opts.pack;
51     this.unpack = opts.unpack;
52   } else {
53     try {
54       var msgpack = require('msgpack');
55       this.pack = msgpack.pack;
56       this.unpack = msgpack.unpack;
57     } catch (e) {
58       this.pack = JSON.stringify;
59       this.unpack = JSON.parse;
60     }
61   }
62
63   var redis = opts.redis || require('redis')
64     , RedisClient = redis.RedisClient;
65
66   // initialize a pubsub client and a regular client
67   if (opts.redisPub instanceof RedisClient) {
68     this.pub = opts.redisPub;
69   } else {
70     opts.redisPub || (opts.redisPub = {});
71     this.pub = redis.createClient(opts.redisPub.port, opts.redisPub.host, opts.redisPub);
72   }
73   if (opts.redisSub instanceof RedisClient) {
74     this.sub = opts.redisSub;
75   } else {
76     opts.redisSub || (opts.redisSub = {});
77     this.sub = redis.createClient(opts.redisSub.port, opts.redisSub.host, opts.redisSub);
78   }
79   if (opts.redisClient instanceof RedisClient) {
80     this.cmd = opts.redisClient;
81   } else {
82     opts.redisClient || (opts.redisClient = {});
83     this.cmd = redis.createClient(opts.redisClient.port, opts.redisClient.host, opts.redisClient);
84   }
85
86   Store.call(this, opts);
87
88   this.sub.setMaxListeners(0);
89   this.setMaxListeners(0);
90 };
91
92 /**
93  * Inherits from Store.
94  */
95
96 Redis.prototype.__proto__ = Store.prototype;
97
98 /**
99  * Publishes a message.
100  *
101  * @api private
102  */
103
104 Redis.prototype.publish = function (name) {
105   var args = Array.prototype.slice.call(arguments, 1);
106   this.pub.publish(name, this.pack({ nodeId: this.nodeId, args: args }));
107   this.emit.apply(this, ['publish', name].concat(args));
108 };
109
110 /**
111  * Subscribes to a channel
112  *
113  * @api private
114  */
115
116 Redis.prototype.subscribe = function (name, consumer, fn) {
117   this.sub.subscribe(name);
118
119   if (consumer || fn) {
120     var self = this;
121
122     self.sub.on('subscribe', function subscribe (ch) {
123       if (name == ch) {
124         function message (ch, msg) {
125           if (name == ch) {
126             msg = self.unpack(msg);
127
128             // we check that the message consumed wasnt emitted by this node
129             if (self.nodeId != msg.nodeId) {
130               consumer.apply(null, msg.args);
131             }
132           }
133         };
134
135         self.sub.on('message', message);
136
137         self.on('unsubscribe', function unsubscribe (ch) {
138           if (name == ch) {
139             self.sub.removeListener('message', message);
140             self.removeListener('unsubscribe', unsubscribe);
141           }
142         });
143
144         self.sub.removeListener('subscribe', subscribe);
145
146         fn && fn();
147       }
148     });
149   }
150
151   this.emit('subscribe', name, consumer, fn);
152 };
153
154 /**
155  * Unsubscribes
156  *
157  * @api private
158  */
159
160 Redis.prototype.unsubscribe = function (name, fn) {
161   this.sub.unsubscribe(name);
162
163   if (fn) {
164     var client = this.sub;
165
166     client.on('unsubscribe', function unsubscribe (ch) {
167       if (name == ch) {
168         fn();
169         client.removeListener('unsubscribe', unsubscribe);
170       }
171     });
172   }
173
174   this.emit('unsubscribe', name, fn);
175 };
176
177 /**
178  * Destroys the store
179  *
180  * @api public
181  */
182
183 Redis.prototype.destroy = function () {
184   Store.prototype.destroy.call(this);
185
186   this.pub.end();
187   this.sub.end();
188   this.cmd.end();
189 };
190
191 /**
192  * Client constructor
193  *
194  * @api private
195  */
196
197 function Client (store, id) {
198   Store.Client.call(this, store, id);
199 };
200
201 /**
202  * Inherits from Store.Client
203  */
204
205 Client.prototype.__proto__ = Store.Client;
206
207 /**
208  * Redis hash get
209  *
210  * @api private
211  */
212
213 Client.prototype.get = function (key, fn) {
214   this.store.cmd.hget(this.id, key, fn);
215   return this;
216 };
217
218 /**
219  * Redis hash set
220  *
221  * @api private
222  */
223
224 Client.prototype.set = function (key, value, fn) {
225   this.store.cmd.hset(this.id, key, value, fn);
226   return this;
227 };
228
229 /**
230  * Redis hash del
231  *
232  * @api private
233  */
234
235 Client.prototype.del = function (key, fn) {
236   this.store.cmd.hdel(this.id, key, fn);
237   return this;
238 };
239
240 /**
241  * Redis hash has
242  *
243  * @api private
244  */
245
246 Client.prototype.has = function (key, fn) {
247   this.store.cmd.hexists(this.id, key, function (err, has) {
248     if (err) return fn(err);
249     fn(null, !!has);
250   });
251   return this;
252 };
253
254 /**
255  * Destroys client
256  *
257  * @param {Number} number of seconds to expire data
258  * @api private
259  */
260
261 Client.prototype.destroy = function (expiration) {
262   if ('number' != typeof expiration) {
263     this.store.cmd.del(this.id);
264   } else {
265     this.store.cmd.expire(this.id, expiration);
266   }
267
268   return this;
269 };