Skip to content

Commit

Permalink
Add functionality to copy revision on activation. This enables nginx …
Browse files Browse the repository at this point in the history
…to do the lookup as redis support is very limited.

change copyToKey to activeContentSuffix add to readme

update readme

remove copyOnActivate boolean

update tests
  • Loading branch information
arenoir committed Dec 10, 2015
1 parent ddfdaa8 commit bf3ecac
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 16 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ The unique revision number for the version of the file being uploaded to Redis.

*Default:* `context.commandLineArgs.revisionKey || context.revisionData.revisionKey`

### activeContentSuffix

The suffix to be used for the Redis key under which the activated revision content will be stored in Redis. By default this option will be `"current-content"`. This makes the default activated revision in Redis looks like: `project.name() + ':index:current-content'`

This makes it possible to serve content completely from within NGINX using the [redis](https://www.nginx.com/resources/wiki/modules/redis/) module without doing a primary key lookup.

```
server {
location / {
set $redis_key project-name:index:current-content;
redis_pass name:6379;
default_type text/html;
}
}
```

*Default:* `current-content`

### allowOverwrite

A flag to specify whether the revision should be overwritten if it already exists in Redis.
Expand Down
15 changes: 9 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
return context.project.name() + ':index';
},
activationSuffix: 'current',
activeContentSuffix: 'current-content',
didDeployMessage: function(context){
var revisionKey = context.revisionData && context.revisionData.revisionKey;
var activatedRevisionKey = context.revisionData && context.revisionData.activatedRevisionKey;
Expand All @@ -62,7 +63,8 @@ module.exports = {
if (!this.pluginConfig.url) {
['host', 'port'].forEach(this.applyDefaultConfigProperty.bind(this));
}
['filePattern', 'distDir', 'keyPrefix', 'activationSuffix', 'revisionKey', 'didDeployMessage', 'redisDeployClient', 'maxRecentUploads'].forEach(this.applyDefaultConfigProperty.bind(this));

['filePattern', 'distDir', 'keyPrefix', 'activationSuffix', 'activeContentSuffix', 'revisionKey', 'didDeployMessage', 'redisDeployClient', 'maxRecentUploads'].forEach(this.applyDefaultConfigProperty.bind(this));

this.log('config ok', { verbose: true });
},
Expand Down Expand Up @@ -100,13 +102,14 @@ module.exports = {
},

activate: function(/* context */) {
var redisDeployClient = this.readConfig('redisDeployClient');
var revisionKey = this.readConfig('revisionKey');
var keyPrefix = this.readConfig('keyPrefix');
var activationSuffix = this.readConfig('activationSuffix');
var redisDeployClient = this.readConfig('redisDeployClient');
var revisionKey = this.readConfig('revisionKey');
var keyPrefix = this.readConfig('keyPrefix');
var activationSuffix = this.readConfig('activationSuffix');
var activeContentSuffix = this.readConfig('activeContentSuffix');

this.log('Activating revision `' + revisionKey + '`', { verbose: true });
return Promise.resolve(redisDeployClient.activate(keyPrefix, revisionKey, activationSuffix))
return Promise.resolve(redisDeployClient.activate(keyPrefix, revisionKey, activationSuffix, activeContentSuffix))
.then(this.log.bind(this, '✔ Activated revision `' + revisionKey + '`', {}))
.then(function(){
return {
Expand Down
37 changes: 31 additions & 6 deletions lib/redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,11 @@ module.exports = CoreObject.extend({
});
},

activate: function(keyPrefix, revisionKey, activationSuffix) {
var currentKey = keyPrefix + ':' + activationSuffix;

activate: function(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) {
return Promise.resolve()
.then(this._listRevisions.bind(this, keyPrefix))
.then(this._validateRevisionKey.bind(this, revisionKey))
.then(this._activateRevisionKey.bind(this, currentKey, revisionKey));
.then(this._activateRevision.bind(this, keyPrefix, revisionKey, activationSuffix, activeContentSuffix));
},

fetchRevisions: function(keyPrefix) {
Expand Down Expand Up @@ -90,9 +88,36 @@ module.exports = CoreObject.extend({
return revisions.indexOf(revisionKey) > -1 ? Promise.resolve() : Promise.reject('`' + revisionKey + '` is not a valid revision key');
},

_activateRevisionKey: function(currentKey, revisionKey) {
_activateRevisionKey: function(keyPrefix, revisionKey, activationSuffix) {
var currentKey = keyPrefix + ':' + activationSuffix;

return this._client.set(currentKey, revisionKey);
},

_activateRevision: function(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) {
if (activeContentSuffix) {
return this._copyRevisionAndActivateRevisionKey(keyPrefix, revisionKey, activationSuffix, activeContentSuffix);
}

return this._activateRevisionKey(keyPrefix, revisionKey, activationSuffix);
},

_copyRevisionAndActivateRevisionKey: function(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) {
var client = this._client;
return client.set(currentKey, revisionKey);
var _this = this;
var activeContentKey = keyPrefix + ':' + activeContentSuffix;
var revisionContentKey = keyPrefix + ':' + revisionKey;

return new Promise(function(resolve, reject) {
client.get(revisionContentKey).then(
function(value) {
client.set(activeContentKey, value).then(function() {
_this._activateRevisionKey(keyPrefix, revisionKey, activationSuffix).then(resolve, reject);
});
},
reject
);
});
},

_uploadIfKeyDoesNotExist: function(redisKey, value) {
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/index-nodetest.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ describe('redis plugin', function() {

return previous;
}, []);
assert.equal(messages.length, 10);
assert.equal(messages.length, 11);
});
it('adds default config to the config object', function() {
plugin.configure(context);
Expand Down Expand Up @@ -310,7 +310,7 @@ describe('redis plugin', function() {

return previous;
}, []);
assert.equal(messages.length, 9);
assert.equal(messages.length, 10);
});
it('does not add default config to the config object', function() {
plugin.configure(context);
Expand Down Expand Up @@ -350,7 +350,7 @@ describe('redis plugin', function() {

return previous;
}, []);
assert.equal(messages.length, 9)
assert.equal(messages.length, 10)
});
it('does not add default config to the config object', function() {
plugin.configure(context);
Expand Down Expand Up @@ -390,7 +390,7 @@ describe('redis plugin', function() {

return previous;
}, []);
assert.equal(messages.length, 8);
assert.equal(messages.length, 9);
});

it('does not add default config to the config object', function() {
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/lib/redis-nodetest.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,39 @@ describe('redis', function() {
assert.equal(redisValue, 'c');
});
});

it('copies revision to the activeContentSuffix', function() {
var redisKey, redisValue;

var redisClient = new FakeRedis(FakeClient.extend({
_db: {
"key-prefix:a": "first revision content",
"key-prefix:b": "second revision content",
"key-prefix:c": "third revision content"
},

get: function(key) {
return Promise.resolve(this._db[key]);
},
set: function(key, value) {
this._db[key] = value;
return Promise.resolve(value);
},
}));

var redis = new Redis({}, redisClient);

redis._client.recentRevisions = ['a', 'b', 'c'];

var activate = redis.activate('key-prefix', 'c', 'current-id', 'current-content').then(function() {
return redis._client.get('key-prefix:current-content');
});

return assert.isFulfilled(activate)
.then(function(result) {
assert.equal(result, "third revision content");
});
});
});

describe('#fetchRevisions', function() {
Expand Down

0 comments on commit bf3ecac

Please sign in to comment.