Skip to content

Commit

Permalink
Support late cache provision. Closes #3077. Closes #3078. Closes #3079.
Browse files Browse the repository at this point in the history
Closes #3080. Closes #3081. Closes #3082. Closes #3083
  • Loading branch information
hueniverse committed Mar 9, 2016
1 parent 6804ac2 commit be547a9
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 71 deletions.
36 changes: 35 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 13.0.x API Reference
# 13.1.x API Reference

- [Server](#server)
- [`new Server([options])`](#new-serveroptions)
Expand All @@ -23,6 +23,7 @@
- [`server.auth.test(strategy, request, next)`](#serverauthteststrategy-request-next)
- [`server.bind(context)`](#serverbindcontext)
- [`server.cache(options)`](#servercacheoptions)
- [`server.cache.provision(options, [callback])`](#servercacheprovisionoptions-callback)
- [`server.connection([options])`](#serverconnectionoptions)
- [`server.decorate(type, property, method, [options])`](#serverdecoratetype-property-method-options)
- [`server.dependency(dependencies, [after])`](#serverdependencydependencies-after)
Expand Down Expand Up @@ -796,6 +797,39 @@ cache.set('norway', { capital: 'oslo' }, null, (err) => {
});
```

### `server.cache.provision(options, [callback])`

Provisions a server cache as described in ['server.cache`](#server.config.cache) where:
- `options` - same as the server `cache` configuration options.
- `callback` - the callback method when cache provisioning is completed or failed with the
signature `function(err)` where:
- `err` - any cache startup error condition.

If no `callback` is provided, a `Promise` object is returned.

Note that if the server has been initialized or started, the cache will be automatically started
to match the state of any other provisioned server cache.

```js
const server = new Hapi.Server();
server.connection({ port: 80 });

server.initialize((err) => {

server.cache.provision({ engine: require('catbox-memory'), name: 'countries' }, (err) => {

const cache = server.cache({ cache: 'countries', expiresIn: 60 * 60 * 1000 });
cache.set('norway', { capital: 'oslo' }, null, (err) => {

cache.get('norway', (err, value, cached, log) => {

// value === { capital: 'oslo' };
});
});
});
});
```

### `server.connection([options])`

Adds an incoming server connection where:
Expand Down
23 changes: 10 additions & 13 deletions lib/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,19 @@ exports = module.exports = internals.Plugin = function (server, connections, env
};

this.auth = {
default: (opts) => {

this._applyChild('auth.default', 'auth', 'default', [opts]);
},
scheme: (name, scheme) => {

this._applyChild('auth.scheme', 'auth', 'scheme', [name, scheme]);
},
strategy: (name, scheme, mode, opts) => {
default: (opts) => this._applyChild('auth.default', 'auth', 'default', [opts]),
scheme: (name, scheme) => this._applyChild('auth.scheme', 'auth', 'scheme', [name, scheme]),
strategy: (name, scheme, mode, opts) => this._applyChild('auth.strategy', 'auth', 'strategy', [name, scheme, mode, opts]),
test: (name, request, next) => request.connection.auth.test(name, request, next)
};

this._applyChild('auth.strategy', 'auth', 'strategy', [name, scheme, mode, opts]);
},
test: (name, request, next) => {
this.cache.provision = (opts, callback) => {

return request.connection.auth.test(name, request, next);
if (!callback) {
return Promises.wrap(null, this.cache.provision, [opts]);
}

return this.root._createCache(opts, callback);
};

this._single();
Expand Down
33 changes: 16 additions & 17 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ exports.apply = function (type, options, message) {
};


internals.cache = Joi.object({
name: Joi.string().invalid('_default'),
partition: Joi.string(),
shared: Joi.boolean(),
engine: Joi.alternatives([
Joi.object(),
Joi.func()
])
.required()
}).unknown();


internals.access = Joi.object({
entity: Joi.string().valid('user', 'app', 'any'),
scope: [false, Joi.array().items(Joi.string()).single().min(1)]
Expand Down Expand Up @@ -195,11 +183,7 @@ internals.connectionBase = Joi.object({

internals.server = Joi.object({
app: Joi.object().allow(null),
cache: Joi.alternatives([
Joi.func(),
internals.cache,
Joi.array().items(internals.cache).min(1)
]).allow(null),
cache: Joi.allow(null), // Validated elsewhere
connections: internals.connectionBase,
debug: Joi.object({
request: Joi.array().allow(false),
Expand Down Expand Up @@ -280,6 +264,21 @@ internals.routeConfig = internals.routeBase.keys({
});


internals.cacheConfig = Joi.object({
name: Joi.string().invalid('_default'),
partition: Joi.string(),
shared: Joi.boolean(),
engine: Joi.alternatives([
Joi.object(),
Joi.func()
])
.required()
}).unknown();


internals.cache = Joi.array().items(internals.cacheConfig, Joi.func()).min(1).single();


internals.cachePolicy = Joi.object({
cache: Joi.string().allow(null).allow(''),
segment: Joi.string(),
Expand Down
74 changes: 47 additions & 27 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,11 @@ exports = module.exports = internals.Server = function (options) {
};

if (options.cache) {
const caches = [].concat(options.cache);
for (let i = 0; i < caches.length; ++i) {
this._createCache(caches[i]);
}
this._createCache(options.cache);
}

if (!this._caches._default) {
this._createCache({ engine: CatboxMemory }); // Defaults to memory-based
this._createCache([{ engine: CatboxMemory }]); // Defaults to memory-based
}

Plugin.call(this, this, [], '', null);
Expand All @@ -78,34 +75,57 @@ exports = module.exports = internals.Server = function (options) {
Hoek.inherits(internals.Server, Plugin);


internals.Server.prototype._createCache = function (options) {
internals.Server.prototype._createCache = function (options, _callback) {

if (typeof options === 'function') {
options = { engine: options };
}
Hoek.assert(this._state !== 'initializing', 'Cannot provision server cache while server is initializing');

options = Schema.apply('cache', options);

const added = [];
for (let i = 0; i < options.length; ++i) {
let config = options[i];
if (typeof config === 'function') {
config = { engine: config };
}

const name = options.name || '_default';
Hoek.assert(!this._caches[name], 'Cannot configure the same cache more than once: ', name === '_default' ? 'default cache' : name);
const name = config.name || '_default';
Hoek.assert(!this._caches[name], 'Cannot configure the same cache more than once: ', name === '_default' ? 'default cache' : name);

let client = null;
if (typeof config.engine === 'object') {
client = new Catbox.Client(config.engine);
}
else {
const settings = Hoek.clone(config);
settings.partition = settings.partition || 'hapi-cache';
delete settings.name;
delete settings.engine;
delete settings.shared;

client = new Catbox.Client(config.engine, settings);
}

let client = null;
if (typeof options.engine === 'object') {
client = new Catbox.Client(options.engine);
this._caches[name] = {
client: client,
segments: {},
shared: config.shared || false
};

added.push(client);
}
else {
const settings = Hoek.clone(options);
settings.partition = settings.partition || 'hapi-cache';
delete settings.name;
delete settings.engine;
delete settings.shared;

client = new Catbox.Client(options.engine, settings);

if (!_callback) {
return;
}

this._caches[name] = {
client: client,
segments: {},
shared: options.shared || false
};
// Start cache

if (['initialized', 'starting', 'started'].indexOf(this._state) !== -1) {
const each = (client, next) => client.start(next);
return Items.parallel(added, each, _callback);
}

return Hoek.nextTick(_callback)();
};


Expand Down
14 changes: 7 additions & 7 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "hapi",
"description": "HTTP Server framework",
"homepage": "http://hapijs.com",
"version": "13.0.0",
"version": "13.1.0",
"repository": {
"type": "git",
"url": "git://github.com/hapijs/hapi"
Expand All @@ -29,7 +29,7 @@
"hoek": "3.x.x",
"iron": "4.x.x",
"items": "2.x.x",
"joi": "7.x.x",
"joi": "8.x.x",
"kilt": "2.x.x",
"mimos": "3.x.x",
"peekaboo": "2.x.x",
Expand All @@ -42,8 +42,8 @@
"code": "2.x.x",
"handlebars": "4.x.x",
"inert": "3.x.x",
"lab": "9.x.x",
"vision": "2.x.x",
"lab": "10.x.x",
"vision": "4.x.x",
"wreck": "7.x.x"
},
"scripts": {
Expand Down
Loading

0 comments on commit be547a9

Please sign in to comment.