Comments (5)
I'm going to close this issue for now, as it seems like we're past the catbox-disk specific issues. The rest is opinion and you can ignore it all you like =P
The "hapi" way to break up routes into separate files is generally to create them as a plugin
, which gives you control over how they are initialized (and you can bind values/functions to all routes as part of their this
context, which is super helpful). Full explanation here: https://hapijs.com/tutorials/plugins
I tend to group related routes into their own plugins so they can share overlapping functionality, and I typically put each plugin in its own folder for keeping things clean. For this example I broke things into your index.js
(the main server) and summer.js
in the same folder (since all its logic fits cleanly in a single file). Your index.js gets a lot cleaner when you start to break out plugins, and plugins are easy to unit test or turn into node modules to re-use between hapi projects.
I wrote the following from memory, and haven't run it - some debugging may be required:
// index.js
const Hapi = require('hapi');
const Disk = require('catbox-disk');
const server = new Hapi.Server({
port: 9999,
cache: [{
name: 'diskCache',
engine: new Disk({
cachePath: './',
cleanEvery: 3600000,
partition: 'cache'
}),
}]
});
const start = async () => {
await server.register({ plugin: require('./summer') });
await server.start();
console.log('Server running at:', server.info.uri);
};
start();
// summer.js
const Hoek = require('Hoek');
module.exports = {
plugin: {
name: 'summer-plugin',
register: async function(server, options) {
const sumCache = server.cache({
cache: 'diskCache',
segment: 'foo',
expiresIn: 10 * 1000,
generateFunc: async (id) => {
return await add(id.a, id.b);
},
generateTimeout: 2000
});
server.bind({ sumCache }); // binds sumCache to every route registered **within this plugin** after this line
server.route([
{ path: '/add/{a}/{b}', method: 'GET', handler },
]);
},
},
};
const handler = async function(request, h) {
const { a, b } = request.params;
const id = `${a}:${b}`;
return await this.sumCache.get({ id, a, b }); // uses the bound sumCache instance from index.js
};
const add = async (a, b) => {
await Hoek.wait(1000); // Simulate some slow I/O
return Number(a) + Number(b);
};
from catbox-disk.
one step forward, one step back… in order to get this to work, I have to change the cache declaration code to below
cache: [{
name: 'diskCache',
engine: new Disk({
cachePath: '/Users/punkish/Projects/catbox/diskCache',
cleanEvery: 3600000,
partition: 'cache'
})
}]
I also have to change return await sumCache({ id, a, b });
to return await sumCache.get({ id, a, b });
else I get the error that sumCache is not a function
So, the above works when I go to, say, /add/5/2
. However, if I change the params, say, /add/5/9
I get a different error Cannot provision the same cache segment more than once
This is very frustrating, and the mismatch between the documentation and what should be seems to be really uncharacteristic. Suggestions?
from catbox-disk.
Hey @punkish
Sorry for the frustration, the readme could definitely use an update for v17 and above.
I got your code working locally with the following changes (some you might have left out of your example for clarity):
- require
Hoek
- added a fixed
port
value for easier testing - added a
segment
name in theserver.cache
options (this is the only substantive change I made)
After doing this, I was successfully calling multiple /add/x/y routes and getting fast secondary calls to repeated routes. I'm running:
- Hapi v18.1.0
- Catbox v10.0.6
- Node v10.15.1
- catbox-disk v3.0.0
const Hoek = require('Hoek');
const Hapi = require('hapi');
const Disk = require('catbox-disk');
const server = new Hapi.Server({
port: 9999,
cache: [{
name: 'diskCache',
engine: new Disk({
cachePath: './',
cleanEvery: 3600000,
partition: 'cache'
}),
}]
});
const start = async () => {
const add = async (a, b) => {
await Hoek.wait(1000); // Simulate some slow I/O
return Number(a) + Number(b);
};
const sumCache = server.cache({
cache: 'diskCache',
segment: 'foo',
expiresIn: 10 * 1000,
generateFunc: async (id) => {
return await add(id.a, id.b);
},
generateTimeout: 2000
});
server.route({
path: '/add/{a}/{b}',
method: 'GET',
handler: async function (request, h) {
const { a, b } = request.params;
const id = `${a}:${b}`;
return await sumCache.get({ id, a, b });
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
start();
I'll get an updated readme out there momentarily. Let me know if the above example fails for you.
from catbox-disk.
Many thanks @EyePulp. Yes, your suggested code works. The key was to use engine: new Disk(options)
as I noted in my second comment above, which I figured out by looking at your code. However, I think the subsequent problem that I reported, that of the error Cannot provision the same cache segment more than once, that is likely because of my lack of understanding of how things work in the Hapi world. See, I moved the route definition to its own file. So now I have add.js
that looks like so
const Hoek = require('hoek');
const add = async (a, b) => {
await Hoek.wait(1000); // Simulate some slow I/O
return Number(a) + Number(b);
};
module.exports = {
path: '/add/{a}/{b}',
method: 'GET',
handler: async function (request, h) {
const sumCache = request.server.cache({
cache: 'diskCache',
expiresIn: 10 * 1000,
segment: 'foo',
generateFunc: async (id) => {
return await add(id.a, id.b);
},
generateTimeout: 2000
});
const { a, b } = request.params;
const id = `${a}:${b}`;
return await sumCache.get({ id, a, b });
}
}
and the index.js
edited to as below
const start = async () => {
server.route([
require('./routes/add')
]);
await server.start();
console.log('Server running at:', server.info.uri);
};
and that is why I getting the error. A new request causes a new invocation of sumCache()
leading to the error. My question is thus: how can I access the server
variable in an external route file?
from catbox-disk.
ok, if I add module.exports = server
to my index.js and then, in add.js I have const server = require('../index')
then it all works. Of course, I also have to define sumCache
without the request
. My add.js file now looks like this
const Hoek = require('hoek');
const server = require('../index')
const add = async (a, b) => {
await Hoek.wait(1000); // Simulate some slow I/O
return Number(a) + Number(b);
};
const sumCache = server.cache({
cache: 'diskCache',
expiresIn: 10 * 1000,
segment: 'foo',
generateFunc: async (id) => {
return await add(id.a, id.b);
},
generateTimeout: 2000
});
module.exports = {
path: '/add/{a}/{b}',
method: 'GET',
handler: async function (request, h) {
const { a, b } = request.params;
const id = `${a}:${b}`;
return await sumCache.get({ id, a, b });
}
}
My question, is that the right way to do things? That is, if I want to keep my routes in separate files but still access the server methods?
from catbox-disk.
Related Issues (2)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from catbox-disk.