Compare View
Commits (5)
Changes
Showing 3 changed files Inline Diff
gateway/resend-delay.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | const LRU = require('lru-cache'); | 3 | const LRU = require('lru-cache'); |
4 | const moment = require('moment'); | 4 | const moment = require('moment'); |
5 | 5 | ||
6 | const config = require('../config'); | 6 | const config = require('../config'); |
7 | const logger = require('../logger'); | 7 | const logger = require('../logger'); |
8 | 8 | ||
9 | const resendHandlers = LRU({ | 9 | const resendHandlers = LRU({ |
10 | max: (( config && config.auto_resend && config.auto_resend.max_handler ) ? Number(config.auto_resend.max_handler) : 0) || 5000, | 10 | max: (( config && config.auto_resend && config.auto_resend.max_handler ) ? Number(config.auto_resend.max_handler) : 0) || 5000, |
11 | maxAge: 1000 * 3600 * 24 | 11 | maxAge: 1000 * 3600 * 24 |
12 | }); | 12 | }); |
13 | 13 | ||
14 | function isEnabled() { | 14 | function isEnabled() { |
15 | return config && config.auto_resend && Number(config.auto_resend.delay_ms) && Number(config.auto_resend.max_retry); | 15 | return config && config.auto_resend && Number(config.auto_resend.delay_ms) && Number(config.auto_resend.max_retry); |
16 | } | 16 | } |
17 | 17 | ||
18 | function _resend(task, request) { | 18 | function _resend(task, request) { |
19 | const trx_date = moment(task.created).format('YYYYMMDD'); | 19 | const trx_date = moment(task.created).format('YYYYMMDD'); |
20 | if (trx_date !== moment().format('YYYYMMDD')) { | 20 | if (trx_date !== moment().format('YYYYMMDD')) { |
21 | logger.info('SDK-RESEND-DELAY: skip resend because of different trx date', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product, created: task.created}); | 21 | logger.info('SDK-RESEND-DELAY: skip resend because of different trx date', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product, created: task.created}); |
22 | return; | 22 | return; |
23 | } | 23 | } |
24 | 24 | ||
25 | logger.verbose('SDK-RESEND-DELAY: Resending trx', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product, created: task.created}); | 25 | logger.verbose('SDK-RESEND-DELAY: Resending trx', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product, created: task.created}); |
26 | request(task); | 26 | request(task); |
27 | } | 27 | } |
28 | 28 | ||
29 | function cancel(_task) { | 29 | function cancel(_task) { |
30 | const trx_id = ( typeof _task === 'string' ) ? _task : _task.trx_id; | 30 | const trx_id = ( typeof _task === 'string' ) ? _task : _task.trx_id; |
31 | if (!trx_id) { | 31 | if (!trx_id) { |
32 | logger.warn('SDK-RESEND-DELAY: Skipping cancel because of undefined trx_id'); | ||
33 | return; | ||
34 | } | ||
32 | logger.warn('SDK-RESEND-DELAY: Skipping cancel because of undefined trx_id'); | 35 | |
33 | return; | 36 | const oldHandler = resendHandlers.get(trx_id); |
34 | } | 37 | if (!oldHandler) { |
38 | config.debug_sdk_resend_delay && logger.verbose('SDK-RESEND-DELAY: Skipping cancel because of undefined oldHandler', {trx_id: trx_id}); | ||
39 | return; | ||
40 | } | ||
35 | 41 | ||
36 | const oldHandler = resendHandlers.get(trx_id); | 42 | const task = oldHandler.task; |
37 | if (!oldHandler) { | 43 | logger.verbose('SDK-RESEND-DELAY: Canceling task', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product}); |
38 | config.debug_sdk_resend_delay && logger.verbose('SDK-RESEND-DELAY: Skipping cancel because of undefined oldHandler', {trx_id: trx_id}); | 44 | |
39 | return; | 45 | if (oldHandler.handler) { clearTimeout(oldHandler.handler); } |
40 | } | 46 | resendHandlers.del(trx_id); |
41 | 47 | } | |
42 | const task = oldHandler.task; | 48 | |
43 | logger.verbose('SDK-RESEND-DELAY: Canceling task', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product}); | 49 | function register(task, request) { |
44 | 50 | if (!task.trx_id) { | |
45 | if (oldHandler.handler) { clearTimeout(oldHandler.handler); } | 51 | logger.warn('SDK-RESEND-DELAY: Invalid task on register') |
46 | resendHandlers.del(trx_id); | 52 | return; |
47 | } | 53 | } |
48 | 54 | ||
49 | function register(task, request) { | 55 | if (!request || !config || !config.auto_resend || !Number(config.auto_resend.delay_ms) || !Number(config.auto_resend.max_retry)) { |
50 | if (!task.trx_id) { | 56 | return; |
51 | logger.warn('SDK-RESEND-DELAY: Invalid task on register') | 57 | } |
52 | return; | 58 | |
53 | } | 59 | let retry = config.auto_resend.max_retry; |
54 | 60 | const oldHandler = resendHandlers.get(task.trx_id); | |
55 | if (!request || !config || !config.auto_resend || !Number(config.auto_resend.delay_ms) || !Number(config.auto_resend.max_retry)) { | 61 | if (oldHandler) { |
56 | return; | 62 | retry = oldHandler.retry - 1; |
57 | } | 63 | cancel(task); |
58 | 64 | } | |
59 | let retry = config.auto_resend.max_retry; | 65 | |
60 | const oldHandler = resendHandlers.get(task.trx_id); | 66 | if (retry <= 0) { |
61 | if (oldHandler) { | 67 | logger.verbose('SDK-RESEND-DELAY: Retry exceeded', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product}); |
62 | retry = oldHandler.retry - 1; | 68 | cancel(task); |
63 | cancel(task); | 69 | return; |
64 | } | 70 | } |
65 | 71 | ||
66 | if (retry <= 0) { | 72 | logger.verbose('SDK-RESEND-DELAY: Registering task request', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product, delay_ms: config.auto_resend.delay_ms, retry: retry}); |
67 | logger.verbose('SDK-RESEND-DELAY: Retry exceeded', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product}); | 73 | const handlerData = { |
68 | cancel(task); | 74 | handler: setTimeout( |
69 | return; | 75 | function() { _resend(task, request); }, |
70 | } | 76 | config.auto_resend.delay_ms |
71 | 77 | ), | |
72 | logger.verbose('SDK-RESEND-DELAY: Registering task request', {trx_id: task.trx_id, destination: task.destination, product: task.product, remote_product: task.remote_product, delay_ms: config.auto_resend.delay_ms, retry: retry}); | 78 | task: task, |
73 | const handlerData = { | 79 | retry: retry |
74 | handler: setTimeout( | 80 | } |
75 | function() { _resend(task, request); }, | 81 | |
76 | config.auto_resend.delay_ms | 82 | resendHandlers.set(task.trx_id, handlerData); |
77 | ), | 83 | } |
78 | task: task, | 84 | |
79 | retry: retry | 85 | setInterval( |
80 | } | 86 | function() { |
81 | 87 | resendHandlers.prune(); | |
82 | resendHandlers.set(task.trx_id, handlerData); | 88 | logger.verbose('SDK-RESEND-DELAY: pruned'); |
83 | } | 89 | }, |
84 | 90 | 24 * 3600 * 1000 | |
85 | setInterval( | 91 | ) |
86 | function() { | 92 | |
87 | resendHandlers.prune(); | 93 | exports.cancel = cancel; |
88 | logger.verbose('SDK-RESEND-DELAY: pruned'); | 94 | exports.register = register; |
89 | }, | 95 | exports.isEnabled = isEnabled; |
90 | 24 * 3600 * 1000 | 96 |
package.json
1 | { | 1 | { |
2 | "name": "komodo-sdk", | 2 | "name": "komodo-sdk", |
3 | "version": "1.26.3", | 3 | "version": "1.26.4", |
4 | "description": "SDK for Komodo", | 4 | "description": "SDK for Komodo", |
5 | "main": "index.js", | 5 | "main": "index.js", |
6 | "scripts": { | 6 | "scripts": { |
7 | "test": "mocha", | 7 | "test": "mocha", |
8 | "postversion": "git push && git push --tags" | 8 | "postversion": "git push && git push --tags" |
9 | }, | 9 | }, |
10 | "repository": { | 10 | "repository": { |
11 | "type": "git", | 11 | "type": "git", |
12 | "url": "git@gitlab.kodesumber.com:komodo/komodo-sdk.git" | 12 | "url": "git@gitlab.kodesumber.com:komodo/komodo-sdk.git" |
13 | }, | 13 | }, |
14 | "keywords": [ | 14 | "keywords": [ |
15 | "ppob", | 15 | "ppob", |
16 | "payment", | 16 | "payment", |
17 | "komodo" | 17 | "komodo" |
18 | ], | 18 | ], |
19 | "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>", | 19 | "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>", |
20 | "license": "ISC", | 20 | "license": "ISC", |
21 | "dependencies": { | 21 | "dependencies": { |
22 | "basic-auth": "^2.0.0", | 22 | "basic-auth": "^2.0.0", |
23 | "body-parser": "^1.18.2", | 23 | "body-parser": "^1.18.2", |
24 | "dot-object": "^1.7.0", | 24 | "dot-object": "^1.7.0", |
25 | "express": "^4.16.3", | 25 | "express": "^4.16.3", |
26 | "express-session": "^1.15.6", | 26 | "express-session": "^1.15.6", |
27 | "json-query": "^2.2.2", | 27 | "json-query": "^2.2.2", |
28 | "lru-cache": "^4.1.1", | 28 | "lru-cache": "^4.1.1", |
29 | "macaddress": "^0.2.8", | 29 | "macaddress": "^0.2.8", |
30 | "moment": "^2.19.1", | 30 | "moment": "^2.19.1", |
31 | "node-machine-id": "^1.1.10", | 31 | "node-machine-id": "^1.1.10", |
32 | "node-natural-sort": "^0.8.6", | 32 | "node-natural-sort": "^0.8.6", |
33 | "numeral": "^2.0.6", | 33 | "numeral": "^2.0.6", |
34 | "nunjucks": "^3.0.1", | 34 | "nunjucks": "^3.0.1", |
35 | "redis": "^2.8.0", | 35 | "redis": "^2.8.0", |
36 | "request": "^2.81.0", | 36 | "request": "^2.81.0", |
37 | "sha1": "^1.1.1", | 37 | "sha1": "^1.1.1", |
38 | "simple-git": "^1.80.1", | 38 | "simple-git": "^1.80.1", |
39 | "strftime": "^0.10.0", | 39 | "strftime": "^0.10.0", |
40 | "uniqid": "^4.1.1", | 40 | "uniqid": "^4.1.1", |
41 | "uuid": "^3.1.0", | 41 | "uuid": "^3.1.0", |
42 | "winston": "^2.3.1", | 42 | "winston": "^2.3.1", |
43 | "winston-circular-buffer": "^1.0.0", | 43 | "winston-circular-buffer": "^1.0.0", |
44 | "winston-daily-rotate-file": "^1.4.6" | 44 | "winston-daily-rotate-file": "^1.4.6" |
45 | } | 45 | } |
46 | } | 46 | } |
47 | 47 |
rc-from-msg.js
1 | "use strict"; | 1 | "use strict"; |
2 | 2 | ||
3 | function logOnDebug(msg) { | 3 | function logOnDebug(msg) { |
4 | if (process.env.KOMODO_SDK_DEBUG_RC_FROM_MSG) { | 4 | if (process.env.KOMODO_SDK_DEBUG_RC_FROM_MSG) { |
5 | console.log(msg); | 5 | console.log(msg); |
6 | } | 6 | } |
7 | } | 7 | } |
8 | 8 | ||
9 | function run(msg, rules) { | 9 | function run(msg, rules) { |
10 | if (typeof msg !== 'string') { | 10 | if (typeof msg !== 'string') { |
11 | logOnDebug('RC-FROM-MSG: invalid msg type === ' + typeof msg); | 11 | logOnDebug('RC-FROM-MSG: invalid msg type === ' + typeof msg); |
12 | return; | 12 | return; |
13 | } | 13 | } |
14 | if (!rules) { | 14 | if (!rules) { |
15 | logOnDebug('RC-FROM-MSG: invalid rules'); | 15 | logOnDebug('RC-FROM-MSG: invalid rules'); |
16 | return; | 16 | return; |
17 | } | 17 | } |
18 | if (!rules.length) { | 18 | if (!rules.length) { |
19 | logOnDebug('RC-FROM-MSG: rules is empty'); | 19 | logOnDebug('RC-FROM-MSG: rules is empty'); |
20 | return; | 20 | return; |
21 | } | 21 | } |
22 | 22 | ||
23 | const rules_count = rules.length; | 23 | const rules_count = rules.length; |
24 | for(let i = 0; i < rules_count; i++) { | 24 | for(let i = 0; i < rules_count; i++) { |
25 | const rule = rules[i]; | 25 | const rule = rules[i]; |
26 | 26 | ||
27 | if (typeof rule.pattern !== 'string') { | ||
28 | continue; | ||
29 | } | ||
30 | |||
31 | if (typeof rule.rc !== 'string' && typeof rule.result !== 'string') { | ||
32 | continue; | ||
33 | } | ||
34 | |||
27 | if (typeof rule.pattern !== 'string') { | 35 | logOnDebug('RC-FROM-MSG: checking with rule: ' + JSON.stringify(rule)); |
28 | continue; | 36 | const re = (typeof rule.flags === 'string') ? new RegExp(rule.pattern, rule.flags) : new RegExp(rule.pattern); |
29 | } | 37 | if (msg.search(re) > 0) { |
30 | 38 | logOnDebug('RC-FROM-MSG: match with rule: ' + JSON.stringify(rule)); | |
31 | if (typeof rule.rc !== 'string' && typeof rule.result !== 'string') { | 39 | return rule.rc || rule.result; |
32 | continue; | 40 | } |
33 | } | 41 | } |
34 | 42 | } | |
35 | logOnDebug('RC-FROM-MSG: checking with rule: ' + JSON.stringify(rule)); | 43 | |
36 | const re = (typeof rule.flags === 'string') ? new RegExp(rule.pattern, rule.flags) : new RegExp(rule.pattern); | 44 | module.exports = run; |
37 | if (msg.search(re) > 0) { | 45 |