UNPKG

7.77 kBJavaScriptView Raw
1//- JavaScript source code
2
3//- defs-redis.js ~~
4//
5// The first step here was just to get things running with plain old arrays in
6// JavaScript, and I accomplished that. The next step is to jettison anything
7// that hinders performance, since it's downright sinful to choose a platform
8// like Node.js + Redis and then squander cycles needlessly ...
9//
10// ~~ (c) SRW, 23 Nov 2012
11// ~~ last updated 07 Aug 2014
12
13(function () {
14 'use strict';
15
16 // Pragmas
17
18 /*jshint maxparams: 2, quotmark: single, strict: true */
19
20 /*jslint indent: 4, maxlen: 80, node: true */
21
22 /*properties
23 auth, avar_ttl, body, ceil, collect_garbage, createClient,
24 detect_buffers, enable_offline_queue, error, exec, exists, expire,
25 exports, forEach, get_avar, get_list, hget, hmset, hostname, isMaster,
26 keys, length, log, multi, no_ready_check, on, parse, parser, port,
27 quit, redis, replace, return_buffers, sadd, set_avar, smembers,
28 socket_nodelay, split, srem, status
29 */
30
31 // Declarations
32
33 var cluster, redis, url;
34
35 // Definitions
36
37 cluster = require('cluster');
38
39 redis = require('redis');
40
41 url = require('url');
42
43 // Out-of-scope definitions
44
45 module.exports = function (options) {
46 // This function needs documentation.
47 var collect_garbage, conn, db, exp_date, get_avar, get_list, set_avar;
48
49 collect_garbage = function () {
50 // This function needs documentation.
51 var remaining, seek_and_destroy;
52 seek_and_destroy = function (queue) {
53 // This function needs documentation.
54 var box = queue.replace(/^\$\:([\w\-]+)[&][\w\-]+/, '$1');
55 db.smembers(queue, function (err, response) {
56 // This function needs documentation.
57 if (err !== null) {
58 console.error('Error:', err);
59 return;
60 }
61 var callback, n;
62 callback = function () {
63 // This function needs documentation.
64 n -= 1;
65 if (n === 0) {
66 remaining -= 1;
67 if (remaining === 0) {
68 console.log('Finished collecting garbage.');
69 }
70 }
71 return;
72 };
73 n = response.length;
74 response.forEach(function (key) {
75 // This function needs documentation.
76 db.exists(box + '&' + key, function (err, response) {
77 // This function needs documentation.
78 if (err !== null) {
79 console.error('Error:', err);
80 }
81 if (response === 0) {
82 db.srem(queue, key, function (err) {
83 // This function accepts a second argument,
84 // but I have omitted it because it irritates
85 // JSLint et al. otherwise.
86 if (err !== null) {
87 console.error('Error:', err);
88 }
89 return callback();
90 });
91 } else {
92 callback();
93 }
94 return;
95 });
96 return;
97 });
98 if (n === 0) {
99 callback();
100 }
101 return;
102 });
103 return;
104 };
105 db.keys('$:*', function (err, queues) {
106 // This function needs documentation.
107 if (err !== null) {
108 console.error('Error:', err);
109 return;
110 }
111 remaining = queues.length;
112 queues.forEach(seek_and_destroy);
113 if (remaining === 0) {
114 console.log('Finished collecting garbage.');
115 }
116 return;
117 });
118 return;
119 };
120
121 conn = url.parse(options.redis);
122
123 db = redis.createClient(conn.port, conn.hostname, {
124 // For more information, see http://git.io/PRZ7Bw .
125 detect_buffers: false,
126 enable_offline_queue: true,
127 no_ready_check: true,
128 parser: 'hiredis',
129 return_buffers: false,
130 socket_nodelay: true
131 });
132
133 exp_date = function () {
134 // This function needs documentation.
135 return Math.ceil(options.avar_ttl);
136 };
137
138 get_avar = function (params, callback) {
139 // This function needs documentation.
140 db.hget(params[0] + '&' + params[1], 'body', callback);
141 return;
142 };
143
144 get_list = function (params, callback) {
145 // This function needs documentation.
146 db.smembers('$:' + params[0] + '&' + params[1], callback);
147 return;
148 };
149
150 set_avar = function (params, callback) {
151 // This function needs documentation.
152 var body, box, key, status;
153 if (params.length === 4) {
154 body = params[3];
155 status = params[2];
156 } else {
157 body = params[2];
158 }
159 box = params[0];
160 key = params[1];
161 db.hget(box + '&' + key, 'status', function (err, res) {
162 // This function needs documentation.
163 if (err !== null) {
164 return callback(err, res);
165 }
166 var multi, set1, set2, updated;
167 multi = db.multi();
168 updated = {body: body};
169 if (res !== null) {
170 set1 = '$:' + box + '&' + res;
171 multi.srem(set1, key);
172 }
173 if (status !== undefined) {
174 updated.status = status;
175 set2 = '$:' + box + '&' + updated.status;
176 multi.sadd(set2, key);
177 }
178 multi.hmset(box + '&' + key, updated);
179 multi.expire(box + '&' + key, exp_date());
180 multi.exec(callback);
181 return;
182 });
183 return;
184 };
185
186 db.auth(conn.auth.split(':')[1]);
187
188 db.on('connect', function () {
189 // This function needs documentation.
190 if (cluster.isMaster) {
191 console.log('API: Redis storage is ready.');
192 }
193 return;
194 });
195
196 db.on('end', function () {
197 // This function needs documentation.
198 console.log('(Redis client closed)');
199 return;
200 });
201
202 db.on('error', function (message) {
203 // This function needs documentation.
204 console.error('Error:', message);
205 return;
206 });
207
208 process.on('exit', function () {
209 // This function needs documentation.
210 db.quit();
211 console.log('(Redis client released)');
212 return;
213 });
214
215 return {
216 collect_garbage: collect_garbage,
217 get_avar: get_avar,
218 get_list: get_list,
219 set_avar: set_avar
220 };
221 };
222
223 // That's all, folks!
224
225 return;
226
227}());
228
229//- vim:set syntax=javascript: