anti-same-day-dupe.js 4.1 KB
var redis = require('redis');
var LRU = require('lru-cache');
var moment = require('moment');

var config;
var logger;
var redisClient;

var taskCache = LRU({max: 100, maxAge: 1000 * 3600 * 2});

function createRedisClient(host, port) {
    try {
        redisClient = redis.createClient(port, host);
        logger.verbose(__filename + ': Redis client for task history created');
    } catch(err) {
        logger.warn(__filename + ": Error creating redis client to " + host + ':' + port);
        process.exit(1);
    }
}

function init(options) {
    if (!options) {
        console.log('Undefined options, terminating....');
        process.exit(1);
    }

    if (options.config) {
        config = options.config;
    } else {
        console.log('Undefined options.config, terminating....')
        process.exit(1);
    }

    if (options && options.logger) {
        logger = options.logger;
    } else {
        console.log('Undefined options.logger, terminating....')
        process.exit(1);
    }

    createRedisClient(config.globals.redis_host, config.globals.redis_port);
}

function getKey(task, chipInfo) {
    var today = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYYMMDD');
    return chipInfo + '.antiSameDayDupe.trx.date:' + today + '.rProd:' + task.remoteProduct.toUpperCase() + '.dest:' + task.destination ;
}

function register(task, cb) {
    var key = getKey(task, config.globals.gateway_name);

    taskCache.set(key, task);
    saveToRedis(task,cb);
}

function saveToRedis(task, cb) {
    var key = getKey(task, config.globals.gateway_name);
    logger.verbose('Saving task', {key: key, task: task});

    redisClient.set(key, JSON.stringify(task), function() {
        redisClient.expire(key, 3600*24);
        if (cb) {
            cb();
        }
    });
}

function createDummyTask(remoteProduct, destination) {
    return {
        remoteProduct: remoteProduct,
        destination: destination,
        timestamp: moment().format('YYYYMMDD'),
    }
}

function get(remoteProduct, destination, cb) {
    var dummyTask = createDummyTask(remoteProduct, destination);

    var key = getKey(dummyTask, config.globals.gateway_name);
    var task = taskCache.get(key);

    if (task) {
        cb(null, task);
    }
    else {
        getFromRedis(remoteProduct, destination, cb);
    }
}

function getFromRedis(remoteProduct, destination, cb) {
    var dummyTask = createDummyTask(remoteProduct, destination);

    var key = getKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD'));
    redisClient.get(key, function(err, result) {
        if (err) {
            logger.warn('antiDupe.get: error getting task from redis', {key: key, params: dummyTask});

            cb(err, null);
            return;
        }

        var task = {};

        try {
            task = JSON.parse(result);
        }
        catch(e) {
            logger.warn('antiDupe.get: Can not parse result', {key: key, params: dummyTask, data: result});
            err = "Can not parse task";
            cb(err, null);
            return;
        }

        cb(err, task);
    });
}

function check(task, cbNoDupe, cbDupe, cbDupeWithSameReqId) {
    if (Number(config.globals.no_same_day_dupe_check)) {
        logger.verbose('Skipping same day dupe check because of config.globals.no_same_day_dupe_check');
        cbNoDupe(task);
        return;
    }

    get(task.remoteProduct, task.destination, function(err, archivedTask) {
        if (err) {
            logger.warn('Error on checking same day duplicate', {task: task});
            cbNoDupe(task);
            return;
        }

        if (archivedTask && archivedTask.requestId) {
            if (task.requestId == archivedTask.requestId) {
                logger.verbose('Duplicate trx on same day with same requestId', {task: task});
                cbDupeWithSameReqId(task);
                return;
            }

            logger.verbose('Duplicate trx on same day', {task: task, archivedTask: archivedTask});
            cbDupe(task);
            return;
        }

        register(task, function() {
            cbNoDupe(task);
        });
    });
}

exports.init = init;
exports.check = check;