Commit 2e4ed981f77dfb3b8d5eb8de4aa199bcf1002030

Authored by Adhidarma Hadiwinoto
1 parent 090288ad17
Exists in master

config.globals.dump_stats_interval_secs

Showing 1 changed file with 11 additions and 1 deletions Inline Diff

1 var redis = require('redis'); 1 var redis = require('redis');
2 var moment = require('moment'); 2 var moment = require('moment');
3 var LRU = require('lru-cache'); 3 var LRU = require('lru-cache');
4 4
5 var config; 5 var config;
6 var logger; 6 var logger;
7 var partner; 7 var partner;
8 var imConfig; 8 var imConfig;
9 var redisClient; 9 var redisClient;
10 10
11 var resendHandlers = LRU({max: 2000, maxAge: 1000 * 3600 * 36}); 11 var resendHandlers = LRU({max: 2000, maxAge: 1000 * 3600 * 36});
12 12
13 function dumpStats() { 13 function dumpStats() {
14 if (config.globals.auto_resend_on_delay_secs) { 14 if (config.globals.auto_resend_on_delay_secs) {
15 logger.verbose('DUMP STATS', { 15 logger.verbose('DUMP STATS', {
16 'resendHandlers:length': resendHandlers.length, 16 'resendHandlers:length': resendHandlers.length,
17 'resendHandlers:itemCount': resendHandlers.itemCount, 17 'resendHandlers:itemCount': resendHandlers.itemCount,
18 }); 18 });
19 } 19 }
20 } 20 }
21 21
22 function dumpStatsPeriodic() {
23 var dumpStatsInterval = 1000 * 30;
24 if (config.globals.dump_stats_interval_secs) {
25 dumpStatsInterval = config.globals.dump_stats_interval_secs;
26 }
27 logger.verbose('Dump stats every ' + dumpStatsInterval / 1000 + ' secs (' + config.globals.dump_stats_interval_secs +')');
28 setInterval(dumpStats, config.globals.dump_stats_interval_secs);
29 }
30
22 function init(options) { 31 function init(options) {
23 if (options && options.config) { 32 if (options && options.config) {
24 config = options.config; 33 config = options.config;
25 } 34 }
26 35
27 if (options && options.logger) { 36 if (options && options.logger) {
28 logger = options.logger; 37 logger = options.logger;
29 } 38 }
30 39
31 createRedisClient(config.globals.redis_host, config.globals.redis_port); 40 createRedisClient(config.globals.redis_host, config.globals.redis_port);
32 readImConfig(); 41 readImConfig();
33 setInterval(dumpStats, 1000 * 300); 42
43 dumpStatsPeriodic();
34 } 44 }
35 45
36 function createRedisClient(host, port) { 46 function createRedisClient(host, port) {
37 try { 47 try {
38 redisClient = redis.createClient(port, host); 48 redisClient = redis.createClient(port, host);
39 } catch(err) { 49 } catch(err) {
40 logger.warn("Error creating redis client to " + host + ':' + port); 50 logger.warn("Error creating redis client to " + host + ':' + port);
41 } 51 }
42 } 52 }
43 53
44 function readImConfig(filename) { 54 function readImConfig(filename) {
45 55
46 if (!filename) { 56 if (!filename) {
47 filename = process.cwd() + '/config.im.json'; 57 filename = process.cwd() + '/config.im.json';
48 } 58 }
49 59
50 try { 60 try {
51 imConfig = require(filename); 61 imConfig = require(filename);
52 } 62 }
53 catch(e) { 63 catch(e) {
54 imConfig = {}; 64 imConfig = {};
55 } 65 }
56 66
57 logger.verbose('IM Config', {imConfig: imConfig}); 67 logger.verbose('IM Config', {imConfig: imConfig});
58 return imConfig; 68 return imConfig;
59 } 69 }
60 70
61 function getPatternFromMessage(message, pattern, patternMatchIndex) { 71 function getPatternFromMessage(message, pattern, patternMatchIndex) {
62 var re = new RegExp(pattern); 72 var re = new RegExp(pattern);
63 var matches = message.match(re); 73 var matches = message.match(re);
64 74
65 if (!matches) { 75 if (!matches) {
66 return null; 76 return null;
67 } 77 }
68 78
69 if (patternMatchIndex < matches.length) { 79 if (patternMatchIndex < matches.length) {
70 return matches[patternMatchIndex]; 80 return matches[patternMatchIndex];
71 } else { 81 } else {
72 return null; 82 return null;
73 } 83 }
74 } 84 }
75 85
76 function getPatternsFromMessage(message, patterns) { 86 function getPatternsFromMessage(message, patterns) {
77 var patternCount = patterns.length; 87 var patternCount = patterns.length;
78 for (var i = 0; i < patternCount; i++) { 88 for (var i = 0; i < patternCount; i++) {
79 89
80 var pattern = patterns[i]; 90 var pattern = patterns[i];
81 91
82 var result = getPatternFromMessage(message, pattern.pattern, pattern.matchIndex); 92 var result = getPatternFromMessage(message, pattern.pattern, pattern.matchIndex);
83 if (result) { 93 if (result) {
84 return result; 94 return result;
85 } 95 }
86 } 96 }
87 } 97 }
88 98
89 function getTaskKey(task, chipInfo, today) { 99 function getTaskKey(task, chipInfo, today) {
90 if (!chipInfo && config && config.globals && config.globals.gateway_name) { 100 if (!chipInfo && config && config.globals && config.globals.gateway_name) {
91 chipInfo = config.globals.gateway_name; 101 chipInfo = config.globals.gateway_name;
92 } 102 }
93 103
94 if (task.timestamp && !today) { 104 if (task.timestamp && !today) {
95 today = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYYMMDD'); 105 today = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYYMMDD');
96 } 106 }
97 107
98 return chipInfo + '.trx.date:' + today + '.rProduct:' + task.remoteProduct.toUpperCase() + '.dest:' + task.destination ; 108 return chipInfo + '.trx.date:' + today + '.rProduct:' + task.remoteProduct.toUpperCase() + '.dest:' + task.destination ;
99 } 109 }
100 110
101 function saveTask(task, cb) { 111 function saveTask(task, cb) {
102 var key = getTaskKey(task, config.globals.gateway_name); 112 var key = getTaskKey(task, config.globals.gateway_name);
103 logger.verbose('Saving task', {key: key, task: task}); 113 logger.verbose('Saving task', {key: key, task: task});
104 114
105 redisClient.set(key, JSON.stringify(task), function() { 115 redisClient.set(key, JSON.stringify(task), function() {
106 redisClient.expire(key, 3600*24); 116 redisClient.expire(key, 3600*24);
107 if (cb) { 117 if (cb) {
108 cb(); 118 cb();
109 } 119 }
110 }); 120 });
111 } 121 }
112 122
113 function getTask(remoteProduct, destination, cb) { 123 function getTask(remoteProduct, destination, cb) {
114 var dummyTask = { 124 var dummyTask = {
115 remoteProduct: remoteProduct, 125 remoteProduct: remoteProduct,
116 destination: destination, 126 destination: destination,
117 } 127 }
118 128
119 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD')); 129 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD'));
120 redisClient.get(key, function(err, result) { 130 redisClient.get(key, function(err, result) {
121 if (err) { 131 if (err) {
122 logger.verbose('getTask: task not found', {key: key, params: dummyTask}); 132 logger.verbose('getTask: task not found', {key: key, params: dummyTask});
123 133
124 cb(err, null); 134 cb(err, null);
125 return; 135 return;
126 } 136 }
127 137
128 var task = {}; 138 var task = {};
129 139
130 try { 140 try {
131 task = JSON.parse(result); 141 task = JSON.parse(result);
132 } 142 }
133 catch(e) { 143 catch(e) {
134 logger.warn('getTask: Can not parse result', {key: key, params: dummyTask, data: result}); 144 logger.warn('getTask: Can not parse result', {key: key, params: dummyTask, data: result});
135 err = "Can not parse result" 145 err = "Can not parse result"
136 } 146 }
137 cb(err, task); 147 cb(err, task);
138 }); 148 });
139 } 149 }
140 150
141 function deleteTask(remoteProduct, destination) { 151 function deleteTask(remoteProduct, destination) {
142 var dummyTask = { 152 var dummyTask = {
143 remoteProduct: remoteProduct, 153 remoteProduct: remoteProduct,
144 destination: destination, 154 destination: destination,
145 } 155 }
146 156
147 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD')); 157 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD'));
148 158
149 try { 159 try {
150 redisClient.del(key); 160 redisClient.del(key);
151 } 161 }
152 catch(e) {}; 162 catch(e) {};
153 } 163 }
154 164
155 function createMessage(pattern, keywords) { 165 function createMessage(pattern, keywords) {
156 var msg = pattern; 166 var msg = pattern;
157 167
158 for (var key in keywords) { 168 for (var key in keywords) {
159 msg = msg.replace('[' + key + ']', keywords[key]); 169 msg = msg.replace('[' + key + ']', keywords[key]);
160 } 170 }
161 return msg; 171 return msg;
162 } 172 }
163 173
164 function getRemoteProductFromMessage(msg) { 174 function getRemoteProductFromMessage(msg) {
165 return getPatternsFromMessage(msg, imConfig.product_patterns); 175 return getPatternsFromMessage(msg, imConfig.product_patterns);
166 } 176 }
167 177
168 function getDestinationFromMessage(msg) { 178 function getDestinationFromMessage(msg) {
169 return getPatternsFromMessage(msg, imConfig.destination_patterns); 179 return getPatternsFromMessage(msg, imConfig.destination_patterns);
170 } 180 }
171 181
172 function getSnFromMessage(msg) { 182 function getSnFromMessage(msg) {
173 return getPatternsFromMessage(msg, imConfig.sn_patterns); 183 return getPatternsFromMessage(msg, imConfig.sn_patterns);
174 } 184 }
175 185
176 function getRcFromMessage(msg) { 186 function getRcFromMessage(msg) {
177 var rcs = imConfig.response_codes; 187 var rcs = imConfig.response_codes;
178 var rcsCount = rcs.length; 188 var rcsCount = rcs.length;
179 189
180 for (var i = 0; i < rcsCount; i++) { 190 for (var i = 0; i < rcsCount; i++) {
181 191
182 var item = rcs[i]; 192 var item = rcs[i];
183 var re = new RegExp(item.pattern); 193 var re = new RegExp(item.pattern);
184 if (msg.search(re) != -1) { 194 if (msg.search(re) != -1) {
185 return item.rc; 195 return item.rc;
186 } 196 }
187 197
188 } 198 }
189 return '68'; 199 return '68';
190 } 200 }
191 201
192 function isAllowedFrom(sender) { 202 function isAllowedFrom(sender) {
193 if (!config || !config.h2h_out || !config.h2h_out.allowed_response_from) { 203 if (!config || !config.h2h_out || !config.h2h_out.allowed_response_from) {
194 return true; 204 return true;
195 } 205 }
196 206
197 whitelist = config.h2h_out.allowed_response_from.split(','); 207 whitelist = config.h2h_out.allowed_response_from.split(',');
198 whitelistCount = whitelist.length; 208 whitelistCount = whitelist.length;
199 209
200 for(var i=0; i<whitelistCount; i++) { 210 for(var i=0; i<whitelistCount; i++) {
201 if (sender == whitelist[i]) { 211 if (sender == whitelist[i]) {
202 return true; 212 return true;
203 } 213 }
204 } 214 }
205 215
206 return false; 216 return false;
207 } 217 }
208 218
209 function checkForSameDayDuplicate(task, cbNoDupe, cbDupe, cbDupeWithSameReqId) { 219 function checkForSameDayDuplicate(task, cbNoDupe, cbDupe, cbDupeWithSameReqId) {
210 getTask(task.remoteProduct, task.destination, function(err, archivedTask) { 220 getTask(task.remoteProduct, task.destination, function(err, archivedTask) {
211 if (err) { 221 if (err) {
212 logger.warn('Error on checking same day duplicate', {task: task}); 222 logger.warn('Error on checking same day duplicate', {task: task});
213 cbNoDupe(task); 223 cbNoDupe(task);
214 return; 224 return;
215 } 225 }
216 226
217 if (archivedTask && archivedTask.requestId) { 227 if (archivedTask && archivedTask.requestId) {
218 if (cbDupeWithSameReqId && task.requestId == archivedTask.requestId) { 228 if (cbDupeWithSameReqId && task.requestId == archivedTask.requestId) {
219 logger.verbose('Duplicate trx on same day with same requestId', {task: task}); 229 logger.verbose('Duplicate trx on same day with same requestId', {task: task});
220 cbDupeWithSameReqId(task, archivedTask); 230 cbDupeWithSameReqId(task, archivedTask);
221 return; 231 return;
222 } 232 }
223 233
224 logger.verbose('Duplicate trx on same day', {task: task, archivedTask: archivedTask}); 234 logger.verbose('Duplicate trx on same day', {task: task, archivedTask: archivedTask});
225 cbDupe(task, archivedTask); 235 cbDupe(task, archivedTask);
226 return; 236 return;
227 } 237 }
228 238
229 cbNoDupe(task); 239 cbNoDupe(task);
230 }); 240 });
231 } 241 }
232 242
233 function registerResendDelay(task) { 243 function registerResendDelay(task) {
234 if (!task.requestId) { 244 if (!task.requestId) {
235 logger.warn('Invalid task on resendDelay') 245 logger.warn('Invalid task on resendDelay')
236 return; 246 return;
237 } 247 }
238 248
239 if (!config || !config.globals || !config.globals.auto_resend_on_delay_secs) { 249 if (!config || !config.globals || !config.globals.auto_resend_on_delay_secs) {
240 return; 250 return;
241 } 251 }
242 252
243 if (!partner || !partner.topupRequest) { 253 if (!partner || !partner.topupRequest) {
244 logger.warn('Skip request resend delay because partner.topupRequest is not exists'); 254 logger.warn('Skip request resend delay because partner.topupRequest is not exists');
245 return; 255 return;
246 } 256 }
247 257
248 var retry = 10; 258 var retry = 10;
249 var oldHandler = resendHandlers.get(task.requestId); 259 var oldHandler = resendHandlers.get(task.requestId);
250 if (oldHandler) { 260 if (oldHandler) {
251 retry = oldHandler.retry - 1; 261 retry = oldHandler.retry - 1;
252 } 262 }
253 263
254 if (retry <= 0) { 264 if (retry <= 0) {
255 logger.verbose('Resend delay retry exceeded', {task: task}); 265 logger.verbose('Resend delay retry exceeded', {task: task});
256 cancelResendDelay(task); 266 cancelResendDelay(task);
257 return; 267 return;
258 } 268 }
259 269
260 logger.info('Resending task request', {task: task}); 270 logger.info('Resending task request', {task: task});
261 var handlerData = { 271 var handlerData = {
262 handler: setTimeout(partner.topupRequest, config.globals.auto_resend_on_delay_secs, task), 272 handler: setTimeout(partner.topupRequest, config.globals.auto_resend_on_delay_secs, task),
263 task: task, 273 task: task,
264 retry: retry 274 retry: retry
265 } 275 }
266 276
267 resendHandlers.set(task.requestId, handlerData); 277 resendHandlers.set(task.requestId, handlerData);
268 } 278 }
269 279
270 function cancelResendDelay(task) { 280 function cancelResendDelay(task) {
271 if (!task || !task.requestId) { 281 if (!task || !task.requestId) {
272 logger.warn('Invalid task on cancelResendDelay'); 282 logger.warn('Invalid task on cancelResendDelay');
273 return; 283 return;
274 } 284 }
275 285
276 var oldHandler = resendHandlers.get(task.requestId); 286 var oldHandler = resendHandlers.get(task.requestId);
277 if (!oldHandler) { 287 if (!oldHandler) {
278 return; 288 return;
279 } 289 }
280 290
281 logger.verbose('Canceling resend delay', {task: task}); 291 logger.verbose('Canceling resend delay', {task: task});
282 292
283 try { 293 try {
284 if (oldHandler.handler) { 294 if (oldHandler.handler) {
285 clearTimeout(oldHandler.handler); 295 clearTimeout(oldHandler.handler);
286 } 296 }
287 } 297 }
288 catch(e) {}; 298 catch(e) {};
289 299
290 try { 300 try {
291 resendHandlers.del(task.requestId); 301 resendHandlers.del(task.requestId);
292 } 302 }
293 catch(e) {}; 303 catch(e) {};
294 } 304 }
295 305
296 exports.init = init; 306 exports.init = init;
297 exports.start = init; 307 exports.start = init;
298 exports.getPatternFromMessage = getPatternFromMessage; 308 exports.getPatternFromMessage = getPatternFromMessage;
299 exports.getPatternsFromMessage = getPatternsFromMessage; 309 exports.getPatternsFromMessage = getPatternsFromMessage;
300 exports.saveTask = saveTask; 310 exports.saveTask = saveTask;
301 exports.getTask = getTask; 311 exports.getTask = getTask;
302 exports.readImConfig = readImConfig; 312 exports.readImConfig = readImConfig;
303 exports.createMessage = createMessage; 313 exports.createMessage = createMessage;
304 exports.getRemoteProductFromMessage = getRemoteProductFromMessage; 314 exports.getRemoteProductFromMessage = getRemoteProductFromMessage;
305 exports.getDestinationFromMessage = getDestinationFromMessage; 315 exports.getDestinationFromMessage = getDestinationFromMessage;
306 exports.getRcFromMessage = getRcFromMessage; 316 exports.getRcFromMessage = getRcFromMessage;
307 exports.getSnFromMessage = getSnFromMessage; 317 exports.getSnFromMessage = getSnFromMessage;
308 exports.isAllowedFrom = isAllowedFrom; 318 exports.isAllowedFrom = isAllowedFrom;
309 exports.checkForSameDayDuplicate = checkForSameDayDuplicate; 319 exports.checkForSameDayDuplicate = checkForSameDayDuplicate;
310 exports.deleteTask = deleteTask; 320 exports.deleteTask = deleteTask;
311 exports.registerResendDelay = registerResendDelay; 321 exports.registerResendDelay = registerResendDelay;
312 exports.cancelResendDelay = cancelResendDelay; 322 exports.cancelResendDelay = cancelResendDelay;
313 323