GithubHelp home page GithubHelp logo

Comments (5)

EyePulp avatar EyePulp commented on August 19, 2024 1

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.

punkish avatar punkish commented on August 19, 2024

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.

EyePulp avatar EyePulp commented on August 19, 2024

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 the server.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.

punkish avatar punkish commented on August 19, 2024

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.

punkish avatar punkish commented on August 19, 2024

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 photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.