From 827e7b51b5a76cbf7e44efe0725068de80224d73 Mon Sep 17 00:00:00 2001 From: John Crepezzi Date: Fri, 16 Feb 2018 09:52:44 -0500 Subject: [PATCH] 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 --- README.md | 4 +- config.js | 7 ++- lib/document_handler.js | 2 +- lib/document_stores/memcached.js | 83 +++++++++++++++++--------------- 4 files changed, 51 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index f01c68b..0383ff7 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/config.js b/config.js index 52ad004..4b33e28 100644 --- a/config.js +++ b/config.js @@ -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 }, diff --git a/lib/document_handler.js b/lib/document_handler.js index 68985ec..e5a6b56 100644 --- a/lib/document_handler.js +++ b/lib/document_handler.js @@ -123,7 +123,7 @@ DocumentHandler.prototype.chooseKey = function(callback) { } else { callback(key); } - }); + }, true); // Don't bump expirations when key searching }; DocumentHandler.prototype.acceptableKey = function() { diff --git a/lib/document_stores/memcached.js b/lib/document_stores/memcached.js index 2771886..be10db6 100644 --- a/lib/document_stores/memcached.js +++ b/lib/document_stores/memcached.js @@ -1,45 +1,52 @@ -var memcached = require('memcache'); -var winston = require('winston'); +const memcached = require('memcached'); +const winston = require('winston'); -// Create a new store with options -var MemcachedDocumentStore = function(options) { - this.expire = options.expire; - if (!MemcachedDocumentStore.client) { - MemcachedDocumentStore.connect(options); +class MemcachedDocumentStore { + + // Create a new store with options + constructor(options) { + this.expire = options.expire; + + 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 }); - }); -}; + // Create a connection + connect(url) { + this.client = new memcached(url); -// 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); -}; + winston.info(`connecting to memcached on ${url}`); -// 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'); - } - }); -}; + this.client.on('failure', function(error) { + winston.info('error connecting to memcached', {error}); + }); + } + + // Save file in a key + set(key, data, callback, skipExpire) { + this.client.set(key, data, skipExpire ? 0 : this.expire, (error) => { + callback(!error); + }); + } + + // Get a file from a key + 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;