task-history.js 3.15 KB
var redis = require('redis');
var LRU = require('lru-cache');

var config;
var logger;
var redisClient;

var redisExpiredInSeconds = 3600*24*30;
var taskHistory = LRU({max: 20, maxAge: 1000 * 3600 * 2});

function createRedisClient(host, port) {
    if (!host || !port) return;
    
    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) {
    var requestId;

    if (typeof task === 'string') {
        requestId = task;
    } else {
        try {
            requestId = task.requestId;
        }
        catch(e) {
            return;
        }
    }

    return config.globals.gateway_name + '.smithsonian.hist.rid:' + requestId;
}

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

    try {
        taskHistory.set(key, JSON.parse(JSON.stringify(task)));
    } catch (e) { }

    putToRedis(task, cb);
}

function putToRedis(task, cb) {
    if (!redisClient) {
        logger.verbose('Not saving to redis because of undefined redisClient')
        if (cb) { cb(); }
        return;
    }

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

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

function get(task, cb) {
    logger.verbose('Getting task from history', {task: task});
    var key = getKey(task, config.globals.gateway_name);
    var archive = taskHistory.get(key);

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

function getFromRedis(task, cb) {
    if (!redisClient) {
        if (cb) { cb("UNDEFINED_REDIS_CLIENT", null); }
        return;
    }

    var key = getKey(task, config.globals.gateway_name);
    redisClient.get(key, function(err, result) {
        if (err) {
            logger.warn('Error retrieving task from redis', {err: err});
            cb(err, null);
            return;
        }

        var task;
        try {
            task = JSON.parse(result);
        }
        catch(e) {
            logger.warn('Exception on parsing redis result as a json', {err: e});
            cb(e, null);
        }

        cb(null, task);
    })
}

exports.init = init;
exports.get = get;
exports.put = put;