Add "app_builder" type of argument for Plack::Runner #415

wants to merge 1 commit into


None yet

2 participants


when I use Plack::Runner to plackup pice of code to run, i found it can not supply some code ran at each time of the server was loaded (especially reloaded), for exmaple :

package Te::Myblog;
#use HiD; # is a static blog builder
use Plack::Runner;

my $hid = $self->build_hid;
my $app = sub {
     return  Plack::App::File->new(root => $self->destination )->to_app;

my $runner = Plack::Runner->new;
$runner->parse_options('-r', '-R' => $self->source_dir);

then, the plack server will restart when it found the directory 's file changed;
when the server restart, I hope I can do some work incidentally , here is rebuild the blog;

I found the Plack::Runner::locate_app method will treat code ref of app as :


 if (ref $psgi eq 'CODE') {
    return sub { $psgi };

so, I append a pice of code, to satisfy my requirement

hopen you can merge it to your wonderful code. that's great for everyone to use it :)

Very thanks !


I don't think it's a good idea. Also the test is failing.

Plack::Loader might be the right place to look at.

@miyagawa miyagawa closed this Jun 15, 2013

yes, use cod ref ref is urgly ,how to do it with Plack::Loader? very thanks:)


Plack::Loader (and the rest of Plack ecosystem) allows to return an object that overrides to_app to return PSGI app.

You can write a custom to_app method that runs whatever hook, then returns a PSGI app code reference.


would to_app method be called at each time of server was restarted ? I need something be called at the server restarted. I use Plack::Loader::Restarter ( I use -r and -R argument to plack::Runner )

thank you :)




oh,maybe that not works for me, the to_app will be called automatically when app is an object ( at each request but not each time of server restart)and app must be in a external file plan runner to load( but i hope it can be in an object or call back i created in my code )

I think you can do some extends at here:

can pass an object to Plack::Runner::run

can pass an app_builder to Plack::Runner::Run


(at each request but not each time of server restart)

It's called each restart, not each request.

app must be in a external file plan runner to load( but i hope it can be in an object or call back i created in my co de )

No, there's no restriction like that.


maybe I wrong, I just found the code in Plack::Runner::run;

my $app = $self->locate_app(@args);

if (ref $psgi eq 'CODE') {
    return sub { $psgi };

if ($self->{eval}) {
    return build {
        no strict;
        no warnings;
        my $eval = "builder { $self->{eval};";
        $eval .= "Plack::Util::load_psgi(\$psgi);" if $psgi;
        $eval .= "}";
        eval $eval or die $@;

$psgi ||= "app.psgi";

require File::Basename;
$self->loader->watch( File::Basename::dirname($psgi) . "/lib", $psgi );
build { Plack::Util::load_psgi $psgi };


looks like the $psgi either an code ref or an "string" means a .psgi file ; if i pass an object to it, it will treat as a .psgi file string, that's wrong.


Right, reloader doesn't seem to support object.

You just implement an object with to_app, then don't use restarter but use your own watcher.

Or, create an app in .psgi as suggested.

Or subclass Reloader loader that ignores the app object, and specify that loader.


When going back to what you're trying to achieve, I think you're trying to abuse the Plack's restarter process to do your application logic, which i don't think is a good idea at all, since it won't work very well in the production environment.

I recommend you to step back and write your PSGI app that rebuilds the actual file server object with the timer (or a better backend), then swap out the App::File app object inside your application, rather than restarting the actual PSGI container.


at first, I use AnyEvent::Inotify to watch the change and than restart Plack Server,

then found the Plack Server has '-r' and '-R' option, so I want to just use Plack server's watch and restart function ( for reduce code )

the restart and watch function was used in development environment in my senior --- A blog generator tool/ just to test the correctness of generated content not works as a server online at all time;

so use your plack's restarter is suitable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment