Question

I have this:

use Plack::Builder;
my $config_app = sub {...};
my $app = sub {...}

builder {
    mount "/admin" => $config_app;
    mount "/"   => $app;
};

the $config_app saving configuration values into file app.cfg and the $app loading it as config-file. Reading config file in every request is not needed. Need read it at the start of application and re-read it when it is changed.

What is the best way achieve this?

My only idea is: The app will remember the last config_read_time, and in every request will check the modification time of the app.cfg. If the file was modified, will re-read it.

Is here any better solution? (mean some messaging between $config_app and $app, e.g. when $config_app saved the new config will send some message to $app: re-read the config.

Was it helpful?

Solution

There are a bunch of ways to monitor a config file.

Write a config check routine like this:

use constant MIN_CHECK_DELAY => 5;  #SECONDS
use constant CONFIG_FILE => '/etc/wtf.conf';

{
    my $last_changed = 0;
    my $last_check   = 0;

    sub load_config {

        return if $last_check + MIN_CHECK_DELAY <= time;

        return if (stat(CONFIG_FILE))[9] <= $last_check;

        # Do stuff here.

        return;
    }

}

The main thing you need to be careful of is that you don't wind up reloading over and over the second that the file changes.

Now call `load_config() anywhere where you might want a load new round of configuration. Since it always succeeds you don't have to test or do anything smarter than sprinkle it in handy places. Like at the top of your app handler.

This will work great for doing things like turning up logging on a running process, or forcing a reload of some module. There aren't a lot of uses where scaling won't bite you.

You know, if you have a bunch of machines serving this, it won't scale. You'd have to rsync the files changed files around, or worse put them on an NFS mount.

Here's a radical notion: why not use a database?

I hear the cool kids are experimenting with database based web apps these days, and that they actually work pretty well.

In all seriousness, the fun thing about programming and building systems is choosing between design trade-offs. There may be some edge case where passing around a changed file is a brilliant success, and my snarky database comment is shown for utter foolishness. Not sure what that use-case is, but it may exist. You know your use case. Try stuff out. Don't be afraid to be a bit stupid. Sometimes, what seems like a really stupid solution turns out to be surprisingly elegant. However, if the idea turns out to be just dumb, learn from the experience and move on.

OTHER TIPS

Although it's not impossible to call $app (kind of like internal redirects) inside $config_app, i would personally recommend against it.

It should be much easier if you create a separate plain-old Perl class (MyApp::ConfigFile or whatever) and calls the method both from $app and $config_app against a singleton object. Note that the technique only works for a single-process web server environment anyway. If you check the modification time and re-read, that can work in a forked environment such as Starman web server.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top