From 5b0f69a50db71f854623df3b8fd5086f25ce4e91 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 3 Mar 2015 14:28:47 +0000 Subject: [PATCH] added cache to learn words manager --- .../app/coffee/LearnedWordsManager.coffee | 27 +++++++------------ .../spelling/app/coffee/MongoCache.coffee | 8 ++++++ .../coffee/LearnedWordsManagerTests.coffee | 23 +++++++++------- 3 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 services/spelling/app/coffee/MongoCache.coffee diff --git a/services/spelling/app/coffee/LearnedWordsManager.coffee b/services/spelling/app/coffee/LearnedWordsManager.coffee index ede634e06e..9ec96a934a 100644 --- a/services/spelling/app/coffee/LearnedWordsManager.coffee +++ b/services/spelling/app/coffee/LearnedWordsManager.coffee @@ -1,18 +1,11 @@ db = require("./DB") -LRU = require("lru-cache") -cacheOpts = - max: 5000 - maxAge: 1000 * 60 * 60 - -cache = LRU(cacheOpts) +mongoCache = require("./MongoCache") logger = require 'logger-sharelatex' metrics = require('metrics-sharelatex') - - module.exports = LearnedWordsManager = learnWord: (user_token, word, callback = (error)->) -> - cache.del(user_token) + mongoCache.del(user_token) db.spellingPreferences.update { token: user_token }, { @@ -22,19 +15,19 @@ module.exports = LearnedWordsManager = }, callback getLearnedWords: (user_token, callback = (error, words)->) -> - cachedWords = cache.get(user_token) - if cachedWords - logger.info user_token:user_token, "cache hit" - metrics.inc "cache-hit", 0.1 - return callback(null, cachedWords) + mongoCachedWords = mongoCache.get(user_token) + if mongoCachedWords? + logger.info user_token:user_token, "mongoCache hit" + metrics.inc "mongoCache-hit", 0.1 + return callback(null, mongoCachedWords) - metrics.inc "cache-miss", 0.1 - logger.info user_token:user_token, "cache miss" + metrics.inc "mongoCache-miss", 0.1 + logger.info user_token:user_token, "mongoCache miss" db.spellingPreferences.findOne token: user_token, (error, preferences) -> return callback error if error? words = preferences?.learnedWords || [] - cache.set(user_token, words) + mongoCache.set(user_token, words) callback null, words diff --git a/services/spelling/app/coffee/MongoCache.coffee b/services/spelling/app/coffee/MongoCache.coffee new file mode 100644 index 0000000000..eef75ddbde --- /dev/null +++ b/services/spelling/app/coffee/MongoCache.coffee @@ -0,0 +1,8 @@ +LRU = require("lru-cache") +cacheOpts = + max: 5000 + maxAge: 1000 * 60 * 60 + +cache = LRU(cacheOpts) + +module.exports = cache \ No newline at end of file diff --git a/services/spelling/test/unit/coffee/LearnedWordsManagerTests.coffee b/services/spelling/test/unit/coffee/LearnedWordsManagerTests.coffee index 8d7d9f0b35..984beb37b8 100644 --- a/services/spelling/test/unit/coffee/LearnedWordsManagerTests.coffee +++ b/services/spelling/test/unit/coffee/LearnedWordsManagerTests.coffee @@ -3,7 +3,8 @@ chai = require 'chai' expect = chai.expect SandboxedModule = require('sandboxed-module') modulePath = require('path').join __dirname, '../../../app/js/LearnedWordsManager' - +assert = require("chai").assert +should = require("chai").should() describe "LearnedWordsManager", -> beforeEach -> @token = "a6b3cd919ge" @@ -11,8 +12,13 @@ describe "LearnedWordsManager", -> @db = spellingPreferences: update: sinon.stub().callsArg(3) + @cache = + get:sinon.stub() + set:sinon.stub() + del:sinon.stub() @LearnedWordsManager = SandboxedModule.require modulePath, requires: "./DB" : @db + "./MongoCache":@cache describe "learnWord", -> beforeEach -> @@ -49,28 +55,27 @@ describe "LearnedWordsManager", -> it "should return the word list in the callback", -> expect(@callback.calledWith null, @wordList).to.equal true - ### + describe "caching the result", -> it 'should use the cache first if it is primed', (done)-> @wordList = ["apples", "bananas", "pears"] - @cache.get.callsArgWith(1, null, learnedWords: @wordList) + @cache.get.returns(@wordList) @db.spellingPreferences.findOne = sinon.stub() @LearnedWordsManager.getLearnedWords @token, (err, spellings)=> - @db.spellingPreferences.find.called.should.equal false - @wordList.should.equal spellings + @db.spellingPreferences.findOne.called.should.equal false + assert.deepEqual @wordList, spellings done() it 'should set the cache after hitting the db', (done)-> @wordList = ["apples", "bananas", "pears"] - @cache.get.callsArgWith(1) @db.spellingPreferences.findOne = sinon.stub().callsArgWith(1, null, learnedWords: @wordList) @LearnedWordsManager.getLearnedWords @token, (err, spellings)=> - @cache.set.calledWith(@token, learnedWords:@wordList).should.equal true + @cache.set.calledWith(@token, @wordList).should.equal true done() it 'should break cache when update is called', (done)-> @word = "instanton" @LearnedWordsManager.learnWord @token, @word, => - @cache.break.calledWith(@token).should.equal true + @cache.del.calledWith(@token).should.equal true done() - ### +