Commit 827e7b51 authored by John Crepezzi's avatar John Crepezzi
Browse files

Rewrite the memcached client

* Update syntax to ES6
* Use `memcached` instead of `memcache`
* Fix restrictions where expirations weren't pushed forward on GET
* Fix a bug where we were unnecessarily bumping expirations on key search

Closes #201
parent ad7702aa
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -156,9 +156,9 @@ All of which are optional except `type` with very logical default values.

### Memcached

To use memcached storage you must install the `memcache` package via npm
To use memcache storage you must install the `memcached` package via npm

`npm install memcache`
`npm install memcached`

Once you've done that, your config section should look like:

+3 −4
Original line number Diff line number Diff line
@@ -33,10 +33,9 @@
  },

  "storage": {
    "type": "redis",
    "host": "0.0.0.0",
    "port": 6379,
    "db": 2,
    "type": "memcached",
    "host": "127.0.0.1",
    "port": 11211,
    "expire": 2592000
  },

+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ DocumentHandler.prototype.chooseKey = function(callback) {
    } else {
      callback(key);
    }
  });
  }, true); // Don't bump expirations when key searching
};

DocumentHandler.prototype.acceptableKey = function() {
+49 −42
Original line number Diff line number Diff line
var memcached = require('memcache');
var winston = require('winston');
const memcached = require('memcached');
const winston = require('winston');

class MemcachedDocumentStore {

  // Create a new store with options
var MemcachedDocumentStore = function(options) {
  constructor(options) {
    this.expire = options.expire;
  if (!MemcachedDocumentStore.client) {
    MemcachedDocumentStore.connect(options);

    const host = options.host || '127.0.0.1';
    const port = options.port || 11211;
    const url = `${host}:${port}`;
    this.connect(url);
  }
};

  // Create a connection
MemcachedDocumentStore.connect = function(options) {
  var host = options.host || '127.0.0.1';
  var port = options.port || 11211;
  this.client = new memcached.Client(port, host);
  this.client.connect();
  this.client.on('connect', function() {
    winston.info('connected to memcached on ' + host + ':' + port);
  });
  this.client.on('error', function(e) {
    winston.info('error connecting to memcached', { error: e });
  connect(url) {
    this.client = new memcached(url);

    winston.info(`connecting to memcached on ${url}`);

    this.client.on('failure', function(error) {
      winston.info('error connecting to memcached', {error});
    });
};
  }

  // Save file in a key
MemcachedDocumentStore.prototype.set =
function(key, data, callback, skipExpire) {
  MemcachedDocumentStore.client.set(key, data, function(err) {
    err ? callback(false) : callback(true);
  }, skipExpire ? 0 : this.expire);
};
  set(key, data, callback, skipExpire) {
    this.client.set(key, data, skipExpire ? 0 : this.expire, (error) => {
      callback(!error);
    });
  }

  // Get a file from a key
MemcachedDocumentStore.prototype.get = function(key, callback, skipExpire) {
  var _this = this;
  MemcachedDocumentStore.client.get(key, function(err, reply) {
    callback(err ? false : reply);
    if (_this.expire && !skipExpire) {
      winston.warn('store does not currently push forward expirations on GET');
  get(key, callback, skipExpire) {
    this.client.get(key, (error, data) => {
      callback(error ? false : data);

      // Update the key so that the expiration is pushed forward
      if (!skipExpire) {
        this.set(key, data, (updateSucceeded) => {
          if (!updateSucceeded) {
            winston.error('failed to update expiration on GET', {key});
          }
        }, skipExpire);
      }
    });
};
  }

}

module.exports = MemcachedDocumentStore;