<commit_before>/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <<EMAIL>>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Store = require('../store')
  , util = require('../util');

/**
 * Exports the constructor.
 */

module.exports = Redis;

/**
 * Redis store.
 * Options:
 *     - redis (fn) redis constructor, defaults to redis
 *     - redisPub (object) options to pass to the pub redis client
 *     - redisSub (object) options to pass to the sub redis client
 *     - redisClient (object) options to pass to the general redis client
 *     - pack (fn) custom packing, defaults to JSON or msgpack if installed
 *     - unpack (fn) custom packing, defaults to JSON or msgpack if installed
 *
 * @api public
 */

function Redis (opts) {
  opts = opts || {};

  // packing / unpacking mechanism
  if (opts.pack) {
    this.pack = opts.pack;
    this.unpack = opts.unpack;
  } else {
    try {
      var msgpack = require('msgpack');
      this.pack = msgpack.pack;
      this.unpack = msgpack.unpack;
    } catch (e) {
      this.pack = JSON.stringify;
      this.unpack = JSON.parse;
    }
  }

  var redis = opts.redis || require('redis')
    , RedisClient = redis.RedisClient;

  // initialize a pubsub client and a regular client
  if (opts.redisPub instanceof RedisClient) {
    this.pub = opts.redisPub;
  } else {
    opts.redisPub  = opts.redisPub || {};
    this.pub = redis.createClient(opts.redisPub.port, opts.redisPub.host, opts.redisPub);
  }

  if (opts.redisSub instanceof RedisClient) {
    this.sub = opts.redisSub;
  } else {
    opts.redisSub = opts.redisSub || {};
    this.sub = redis.createClient(opts.redisSub.port, opts.redisSub.host, opts.redisSub);
  }

  if (opts.redisClient instanceof RedisClient) {
    this.cmd = opts.redisClient;
  } else {
    opts.redisClient = opts.redisClient || {};
    this.cmd = redis.createClient(opts.redisClient.port, opts.redisClient.host, opts.redisClient);
  }

  Store.call(this, opts);

  this.sub.setMaxListeners(0);
  this.setMaxListeners(0);

  // initialize subscribe, unsubscribe, message event.
  var self = this;

  this.subscribeRepo = {};
  this.unsubscribeRepo = {};
  this.messageConsumers = {};

  this.sub.on('subscribe', function (ch) {
    var sub = self.subscribeRepo[ch];

    if (typeof sub !== 'undefined') {
      delete self.subscribeRepo[ch];
      self.messageConsumers[ch] = sub.consumer;
      util.invoke(sub.fn);
    }
  });

  this.sub.on('unsubscribe', function (ch) {
    delete self.messageConsumers[ch];
    var fn = self.unsubscribeRepo[ch];
    delete self.unsubscribeRepo[ch];
    util.invoke(fn);
  });

  this.sub.on('message', function (ch, msg) {
    util.invoke(self.messageConsumers[ch], msg);
  });
}

/**
 * Inherit from Store
 */

util.inherits(Redis, Store);

/**
 * Initialize redis store
 *
 * @param {Manager} manager
 * @param {Function} cb cb()
 * @api public
 */

Redis.prototype.init = function(manager, cb) {
  this.manager = manager;
  util.invoke(cb);
};

/**
 * Query handshaken data
 *
 * @param {String} id session id
 * @param {Function} cb cb(handshakenData)
 * @api public
 */

Redis.prototype.handshaken = function (id, cb) {
  var self = this;
  this.cmd.get('handshaken:' + id,  function(err, msg) {
    if (err) {
      self.log.error('get handshaken data error:' + err);
      util.invoke(cb);
    } else {
      var handshakenData = self.unpack(msg);
      util.invoke(cb, handshakenData);
    }
  });
};

/**
 * Add handshaken data to redis store
 *
 * @param {String} id session id
 * @param {Object} data handshaken data
 * @param {Function} cb cb(err)
 */

Redis.prototype.onHandshaken = function(id, data, cb) {
  var self = this;
  this.cmd.set('handshaken:' + id, this.pack(data), function(err) {
    if (err) {
      self.log.error('add handshaken data error:' + err);
      util.invoke(cb, err);
    } else {
      // 30 seconds for handshaken expiration
      var timeout = self.manager.get('handshake expiration');
      self.cmd.expire('handshaken:' + id, timeout, cb);
    }
  });
};

/**
 * Check if session id is connected
 *
 * @param {String} id session id
 * @param {Function} cb cb(isConnected)
 * @api public
 */

Redis.prototype.connected = function(id, cb) {
  var self = this;
  this.cmd.get('connected:' + id,  function(err, msg) {
    if (err) {
      self.log.error('check connected err:' + err);
      util.invoke(cb, false);
    } else {
      var connected = self.unpack(msg);
      util.invoke(cb, !!connected);
    }
  });
};

/**
 * Add connected flag
 *
 * @param {String} id session id
 * @param {Function} cb cb(err)
 * @api public<commit_msg>redisStore: optimize redis key set<commit_after>/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <<EMAIL>>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Store = require('../store')
  , util = require('../util');

/**
 * Exports the constructor.
 */

module.exports = Redis;

/**
 * Redis store.
 * Options:
 *     - redis (fn) redis constructor, defaults to redis
 *     - redisPub (object) options to pass to the pub redis client
 *     - redisSub (object) options to pass to the sub redis client
 *     - redisClient (object) options to pass to the general redis client
 *     - pack (fn) custom packing, defaults to JSON or msgpack if installed
 *     - unpack (fn) custom packing, defaults to JSON or msgpack if installed
 *
 * @api public
 */

function Redis (opts) {
  opts = opts || {};

  // packing / unpacking mechanism
  if (opts.pack) {
    this.pack = opts.pack;
    this.unpack = opts.unpack;
  } else {
    try {
      var msgpack = require('msgpack');
      this.pack = msgpack.pack;
      this.unpack = msgpack.unpack;
    } catch (e) {
      this.pack = JSON.stringify;
      this.unpack = JSON.parse;
    }
  }

  var redis = opts.redis || require('redis')
    , RedisClient = redis.RedisClient;

  // initialize a pubsub client and a regular client
  if (opts.redisPub instanceof RedisClient) {
    this.pub = opts.redisPub;
  } else {
    opts.redisPub  = opts.redisPub || {};
    this.pub = redis.createClient(opts.redisPub.port, opts.redisPub.host, opts.redisPub);
  }

  if (opts.redisSub instanceof RedisClient) {
    this.sub = opts.redisSub;
  } else {
    opts.redisSub = opts.redisSub || {};
    this.sub = redis.createClient(opts.redisSub.port, opts.redisSub.host, opts.redisSub);
  }

  if (opts.redisClient instanceof RedisClient) {
    this.cmd = opts.redisClient;
  } else {
    opts.redisClient = opts.redisClient || {};
    this.cmd = redis.createClient(opts.redisClient.port, opts.redisClient.host, opts.redisClient);
  }

  Store.call(this, opts);

  this.sub.setMaxListeners(0);
  this.setMaxListeners(0);

  // initialize subscribe, unsubscribe, message event.
  var self = this;

  this.subscribeRepo = {};
  this.unsubscribeRepo = {};
  this.messageConsumers = {};

  this.sub.on('subscribe', function (ch) {
    var sub = self.subscribeRepo[ch];

    if (typeof sub !== 'undefined') {
      delete self.subscribeRepo[ch];
      self.messageConsumers[ch] = sub.consumer;
      util.invoke(sub.fn);
    }
  });

  this.sub.on('unsubscribe', function (ch) {
    delete self.messageConsumers[ch];
    var fn = self.unsubscribeRepo[ch];
    delete self.unsubscribeRepo[ch];
    util.invoke(fn);
  });

  this.sub.on('message', function (ch, msg) {
    util.invoke(self.messageConsumers[ch], msg);
  });
}

/**
 * Inherit from Store
 */

util.inherits(Redis, Store);

/**
 * Initialize redis store
 *
 * @param {Manager} manager
 * @param {Function} cb cb()
 * @api public
 */

Redis.prototype.init = function(manager, cb) {
  this.manager = manager;
  util.invoke(cb);
};

/**
 * Query handshaken data
 *
 * @param {String} id session id
 * @param {Function} cb cb(handshakenData)
 * @api public
 */

Redis.prototype.handshaken = function (id, cb) {
  var self = this;
  this.cmd.get('handshaken:' + id,  function(err, msg) {
    if (err) {
      self.log.error('get handshaken data error:' + err);
      util.invoke(cb);
    } else {
      var handshakenData = self.unpack(msg);
      util.invoke(cb, handshakenData);
    }
  });
};

/**
 * Add handshaken data to redis store
 *
 * @param {String} id session id
 * @param {Object} data handshaken data
 * @param {Function} cb cb(err)
 */

Redis.prototype.onHandshaken = function(id, data, cb) {
  var self = this;
  this.cmd.setex('handshaken:' + id, self.manager.get('handshake expiration'), this.pack(data), cb);
};

/**
 * Check if session id is connected
 *
 * @param {String} id session id
 * @param {Function} cb cb(isConnected)
 * @api public
 */

Redis.prototype.connected = function(id, cb) {
  var self = this;
  this.cmd.get('connected:' + id,  function(err, msg) {
    if (err) {
      self.log.error('check connected err:' + err);
      util.invoke(cb, false);
    } else {
      var connected = self.unpack(msg);
      util.invoke(cb, !!connected);
    }
  });
};

/**
 * Add connected flag
 *
 * @param {String} id session id
 * @param {Function} cb cb(err)
 * @api public
{'fraction_non_alphanumeric': 0.14930170693859454, 'fraction_numerical': 0.0015517623586787852, 'mean_word_length': 2.973139586085425, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6050699', 'n_tokens_mistral': 3090, 'n_tokens_neox': 3057, 'n_words': 750}