Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add “object” type of argument for Plack::Runner #416

Open
wants to merge 1 commit into from

3 participants

@ChinaXing

just like we discussed in issue : #415

I think support object type of app instead of subroutine type of app is useful ?

I just add two lines of code.

The Test Run passed :)

thanks

@coveralls

Coverage Status

Coverage decreased (-0%) when pulling 61ef380 on ChinaXing:master into ad053a1 on plack:master.

@miyagawa
Owner

Hmm, sorry, as I pointed out in the other thread, a delayed code that builds a PSGI app is a duplication of Loader functionality, so I suggest looking at there. Or, as I also suggested it, you shouldn't try to (ab)use the restarter code and rather run the fork & Filesys::Notify::Simple to rebuild your blog, without relying on the restarter.

@ChinaXing

yes, my solution has used your method.

I add this type of argument of Plack::Runner just want to let Plack::Runner's app argument can support an object.

by now, It only support subroutine as a app argument;

a delayed code that builds a PSGI app is a duplication of Loader functionality, so I suggest looking at there

If pass an subroutine to Plack::Runner::run as the app argument, the subroutine will be wrapped as :

 sub { $app }

(https://github.com/plack/Plack/blob/master/lib/Plack/Runner.pm#L160)
this will do nothing just return the subroutine, no builds action.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 101 additions and 0 deletions.
  1. +18 −0 lib/Plack/Runner.pm
  2. +83 −0 t/Plack-Runner/app_builder.t
View
18 lib/Plack/Runner.pm
@@ -160,6 +160,10 @@ sub locate_app {
return sub { $psgi };
}
+ if (Scalar::Util::blessed($psgi) and $psgi->can('to_app')){
+ return sub { $psgi->to_app };
+ }
+
if ($self->{eval}) {
$self->loader->watch("lib");
return build {
@@ -295,6 +299,20 @@ Plack::Runner - plackup core
$runner->parse_options(@ARGV);
$runner->run($app);
+ # use app builder instead of app
+ use Plack::Runner;
+ my $app_builder => sub {
+ # do some thing here will run every time server loaded
+
+ return sub {
+ # the real app code here
+ }
+ };
+
+ my $runner = Plack::Runner->new;
+ $runner->parse_options(@ARGV);
+ $runner->run(\$app_builder); # use code ref ref
+
=head1 DESCRIPTION
Plack::Runner is the core of L<plackup> runner script. You can create
View
83 t/Plack-Runner/app_builder.t
@@ -0,0 +1,83 @@
+
+use Test::More;
+use Plack::Runner;
+use File::Path (qw/make_path remove_tree/);
+use Test::Requires (qw/LWP::UserAgent Test::MockObject/);
+
+make_path "tmp/m";
+
+my $app = Test::MockObject->new();
+$app->mock(
+ to_app => sub {
+ eval {
+ open my $fh, ">>", "tmp/counter";
+ print $fh "1";
+ close $fh;
+ };
+ return sub {
+ return [ 200, [], ["Hello"] ];
+ }
+ }
+);
+
+my $runner = Plack::Runner->new;
+
+sub counter_ok {
+ my ( $len, $msg ) = @_;
+ my $content = "";
+ eval {
+ open my $fh, "<", "tmp/counter";
+ $content = <$fh>;
+
+ };
+ is $content , "1" x $len, $msg;
+}
+
+$runner->parse_options( -R => 'tmp/m', '-r', -p => 5000 );
+
+my $pid = fork;
+
+if ($pid) {
+ my $timeout = 5;
+ until ( -f "tmp/counter" ) {
+ sleep 1;
+ last if $timeout-- == 0;
+ }
+ if ( $timeout < 0 ) {
+ is 1 < 0, "plack up server failed";
+ kill 'TERM' => $pid;
+ }
+ else {
+ my $ua = LWP::UserAgent->new;
+ my $res = $ua->get('http://127.0.0.1:5000/');
+ ok $res->is_success;
+ is $res->code, 200;
+ is $res->content, 'Hello';
+
+ counter_ok 1, "app builder not run";
+
+ make_path "tmp/m/a";
+ sleep 5;
+
+ counter_ok 2, "app builder run";
+ $res = $ua->get('http://127.0.0.1:5000/');
+ ok $res->is_success;
+ is $res->code, 200;
+ is $res->content, 'Hello';
+
+ remove_tree "tmp/m/a";
+ sleep 5;
+
+ counter_ok 3, "app builder run again";
+
+ kill 'TERM' => $pid;
+ }
+}
+else {
+ $runner->run($app);
+ exit 0;
+}
+
+remove_tree "tmp";
+done_testing;
+
Something went wrong with that request. Please try again.