Skip to content

Commit

Permalink
feat(cache): Add cache layer to entity.datastoreEntity() method
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga committed Mar 18, 2018
1 parent 20ed96f commit 63780e4
Show file tree
Hide file tree
Showing 5 changed files with 925 additions and 30 deletions.
9 changes: 8 additions & 1 deletion lib/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,16 @@ class Entity {
*
* @param {Function} cb Callback
*/
datastoreEntity(cb) {
datastoreEntity(...args) {
const _this = this;
const cb = args.pop();
const options = args[0] || {};

if (this.constructor.__hasCache(options)) {
return this.gstore.cache.keys
.read(this.entityKey, options)
.then(e => onSuccess([e]), onError);
}
return this.gstore.ds.get(this.entityKey).then(onSuccess, onError);

// ------------------------
Expand Down
4 changes: 2 additions & 2 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,13 @@ class Model extends Entity {
options = args.length > 5 ? args[5] : undefined;

const key = this.key(id, ancestors, namespace);
const override = options && options.replace === true;
const replace = options && options.replace === true;

/**
* If options.replace is set to true we don't fetch the entity
* and save the data directly to the specified key, overriding any previous data.
*/
if (override) {
if (replace) {
return saveEntity({ key, data })
.then(onEntityUpdated, onUpdateError);
}
Expand Down
19 changes: 14 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
"description": "gstore-node is a Google Datastore Entity Models tools",
"main": "index.js",
"scripts": {
"lint": "./node_modules/eslint/bin/eslint.js ./lib && eslint ./test",
"pretest": "npm run lint",
"test": "mocha test --recursive",
"commit": "git-cz",
"coverage-old": "istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec --recursive",
"coverage": "nyc mocha test --recursive",
"coveralls": "nyc mocha test --recursive && nyc report --reporter=text-lcov | coveralls && rm -rf ./coverage"
"coveralls": "nyc mocha test --recursive && nyc report --reporter=text-lcov | coveralls && rm -rf ./coverage",
"lint": "./node_modules/eslint/bin/eslint.js ./lib && eslint ./test",
"pretest": "npm run lint",
"test": "mocha test --recursive"
},
"engines": {
"node": ">=6.0"
Expand Down Expand Up @@ -50,6 +51,11 @@
]
},
"license": "ISC",
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"dependencies": {
"@google-cloud/datastore": "^1.3.4",
"arrify": "^1.0.1",
Expand All @@ -67,7 +73,9 @@
"babel-preset-es2015": "^6.24.1",
"cache-manager-redis-store": "^1.4.0",
"chai": "^3.5.0",
"commitizen": "^2.9.6",
"coveralls": "^3.0.0",
"cz-conventional-changelog": "^2.1.0",
"dataloader": "^1.4.0",
"eslint": "^4.18.2",
"eslint-config-airbnb-base": "^12.1.0",
Expand All @@ -80,6 +88,7 @@
"nconf": "^0.10.0",
"nyc": "^11.4.1",
"redis-mock": "^0.21.0",
"sinon": "^4.4.2"
"sinon": "^4.4.2",
"standard-version": "^4.3.0"
}
}
69 changes: 68 additions & 1 deletion test/entity-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ds = require('@google-cloud/datastore')({
});
const datastoreSerializer = require('../lib/serializer').Datastore;
const gstore = require('../lib')();
const gstoreWithCache = require('../')({ namespace: 'entity-with-cache', cache: { ttl: { keys: 600 } } });
const { Schema } = require('../lib')();

const { expect, assert } = chai;
Expand All @@ -23,6 +24,7 @@ describe('Entity', () => {
gstore.modelSchemas = {};
gstore.options = {};
gstore.connect(ds);
gstoreWithCache.connect(ds);

schema = new Schema({
name: { type: 'string', default: 'Mick' },
Expand Down Expand Up @@ -526,7 +528,7 @@ describe('Entity', () => {
});
});

it('should deal with error while fetching the entity', () => {
it('should bubble up error fetching the entity', () => {
const error = { code: 500, message: 'Something went bad' };
sinon.stub(ds, 'get').rejects(error);

Expand Down Expand Up @@ -554,6 +556,71 @@ describe('Entity', () => {
ds.get.restore();
});
});

context('when cache is active', () => {
let key;
let mockData;

beforeEach(() => {
gstore.cache = gstoreWithCache.cache;

key = ModelInstance.key(123);
mockData = { name: 'John' };
mockData[gstore.ds.KEY] = key;
});

afterEach(() => {
// empty the cache
gstore.cache.reset();
delete gstore.cache;
});

it('should get value from cache', () => {
const value = mockData;
const entity = new ModelInstance(mockData);
entity.entityKey = key;

sinon.spy(entity.gstore.cache.keys, 'read');
sinon.stub(ds, 'get').resolves([mockData]);

return gstore.cache.keys.set(key, value)
.then(() => (
entity.datastoreEntity({ ttl: 123456 })
.then((response) => {
assert.ok(!ds.get.called);
expect(response.entityData).include(value);
assert.ok(entity.gstore.cache.keys.read.called);
const { args } = entity.gstore.cache.keys.read.getCall(0);
expect(args[0]).equal(key);
expect(args[1].ttl).equal(123456);

entity.gstore.cache.keys.read.restore();
ds.get.restore();
})
));
});

it('should **not** get value from cache', () => {
const value = mockData;
const entity = new ModelInstance(mockData);
entity.entityKey = key;

sinon.spy(entity.gstore.cache.keys, 'read');
sinon.stub(ds, 'get').resolves([mockData]);

return gstore.cache.keys.set(key, value)
.then(() => (
entity.datastoreEntity({ cache: false })
.then(() => {
assert.ok(ds.get.called);
assert.ok(!entity.gstore.cache.keys.read.called);

entity.gstore.cache.keys.read.restore();
ds.get.restore();
})
));
});
});
});

describe('model()', () => {
Expand Down
Loading

0 comments on commit 63780e4

Please sign in to comment.