Problems mounting multiple webapps
I've been having some issues mounting multiple webapps on a single Plack server according to the documentation (http://search.cpan.org/dist/Dancer/lib/Dancer/Deployment.pod). After reading through the source a bit I managed to get my content served, but the static files are all being handled by the route handlers. It seems that somewhere down the line the 'public' setting is going undef, along with all others presumably. Anyway, the log messages I get are here: http://paste.perldancer.org/29wzxHG7VkVoW, And the psgi I'm using is here: http://paste.perldancer.org/OntvcvVUSY7k Any help or suggestions would be greatly appreciated. -- Alex Kalderimis Software Developer InterMine Cambridge Systems Biology Centre Tennis Court Road - CB2 1QR University of Cambridge ajk59@cam.ac.uk
If anyone is interested, I was able to get three instances of the same app mounted successfully, but I had to additionally specify the 'views' and 'public' settings, as below:
set views => $view_dir; set public => 'public';
The full psgi script is here: http://pb.rbfh.de/23RCNzXyqIiJb Cheers On Fri, 2011-06-10 at 20:21 +0100, Alex Kalderimis wrote:
I've been having some issues mounting multiple webapps on a single Plack server according to the documentation (http://search.cpan.org/dist/Dancer/lib/Dancer/Deployment.pod).
After reading through the source a bit I managed to get my content served, but the static files are all being handled by the route handlers. It seems that somewhere down the line the 'public' setting is going undef, along with all others presumably.
Anyway, the log messages I get are here: http://paste.perldancer.org/29wzxHG7VkVoW,
And the psgi I'm using is here: http://paste.perldancer.org/OntvcvVUSY7k
Any help or suggestions would be greatly appreciated.
On Sat, Jun 11, 2011 at 3:33 PM, Alex Kalderimis <alex@flymine.org> wrote:
If anyone is interested, I was able to get three instances of the same app mounted successfully, but I had to additionally specify the 'views' and 'public' settings, as below:
set views => $view_dir; set public => 'public';
The full psgi script is here: http://pb.rbfh.de/23RCNzXyqIiJb
Hi Alex, I've had luck running my app under nginx reverse proxy. I get nginx to serve the static content directly so my app only handles the dynamic stuff. It was pretty easy to set up and it might simplify your configuration. The only tricks are adding settings to nginx to forward the original Host, user ip, and scheme (to tell https vs http).
Cheers
On Fri, 2011-06-10 at 20:21 +0100, Alex Kalderimis wrote:
I've been having some issues mounting multiple webapps on a single Plack server according to the documentation (http://search.cpan.org/dist/Dancer/lib/Dancer/Deployment.pod).
After reading through the source a bit I managed to get my content served, but the static files are all being handled by the route handlers. It seems that somewhere down the line the 'public' setting is going undef, along with all others presumably.
Anyway, the log messages I get are here: http://paste.perldancer.org/29wzxHG7VkVoW,
And the psgi I'm using is here: http://paste.perldancer.org/OntvcvVUSY7k
Any help or suggestions would be greatly appreciated.
_______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
Hi. I have read this threads. I tried mounting multiple webapps will work. My test code app.psgi is below. ---------------------------------------------------------------------------------------- use Dancer ':syntax'; use Plack::Builder; my $app1 = sub { my $env = shift; get '/' => sub { return "Hello App1"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); }; my $app2 = sub { my $env = shift; get '/' => sub { return "Hello App2"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); }; builder { mount "/app1" => builder{$app1}; mount "/app2" => builder{$app2}; }; ---------------------------------------------------------------------------------------- I invoked app.psgi with single worker. plackup -s Starman --workers 1 -a app.psgi I access /app1 and then /app2 in order. Both times the result is same "Hello App1". But I access /app2 and then /app1 in order. Both times the result is same "Hello App2". when I invoked app.psgi with 5 workers. plackup -s Starman --workers 5 -a app.psgi Access to /app1 and /app2 many times, the Result is mixed. Access to /app1 returns "Hello App1" and "Hello App2" in random. Access to /app2 returns "Hello App2" and "Hello App1" in random. I'm worry that mouting multiple webapps seems does not work. -- Takeshi OKURA
Hello, Although what I'll say do not help you now, it will help you in the future :) When updating Dancer to a more recent version all your Dancer::Request->new($env) will need to be replaced by Dancer::Request->new(env => $env); Now, hopefully somebody can help you with your current problem :) On 13/06/2011 15:00, Takeshi OKURA wrote:
Hi.
I have read this threads. I tried mounting multiple webapps will work. My test code app.psgi is below. ---------------------------------------------------------------------------------------- use Dancer ':syntax'; use Plack::Builder;
my $app1 = sub { my $env = shift; get '/' => sub { return "Hello App1"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
my $app2 = sub { my $env = shift; get '/' => sub { return "Hello App2"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
builder { mount "/app1" => builder{$app1}; mount "/app2" => builder{$app2}; }; ----------------------------------------------------------------------------------------
I invoked app.psgi with single worker. plackup -s Starman --workers 1 -a app.psgi
I access /app1 and then /app2 in order. Both times the result is same "Hello App1".
But I access /app2 and then /app1 in order. Both times the result is same "Hello App2".
when I invoked app.psgi with 5 workers. plackup -s Starman --workers 5 -a app.psgi
Access to /app1 and /app2 many times, the Result is mixed. Access to /app1 returns "Hello App1" and "Hello App2" in random. Access to /app2 returns "Hello App2" and "Hello App1" in random.
I'm worry that mouting multiple webapps seems does not work.
On Mon, Jun 13, 2011 at 03:06:32PM +0100, Alberto Simoes wrote:
Hello,
Although what I'll say do not help you now, it will help you in the future :)
When updating Dancer to a more recent version all your Dancer::Request->new($env) will need to be replaced by Dancer::Request->new(env => $env);
I had noticed this from the latest devel on github - I should probably add in a good error message for catching the old style of request instantiation.
Now, hopefully somebody can help you with your current problem :)
On 13/06/2011 15:00, Takeshi OKURA wrote:
Hi.
I have read this threads. I tried mounting multiple webapps will work. My test code app.psgi is below. ---------------------------------------------------------------------------------------- use Dancer ':syntax'; use Plack::Builder;
my $app1 = sub { my $env = shift; get '/' => sub { return "Hello App1"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
my $app2 = sub { my $env = shift; get '/' => sub { return "Hello App2"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
builder { mount "/app1" => builder{$app1}; mount "/app2" => builder{$app2}; }; ----------------------------------------------------------------------------------------
I invoked app.psgi with single worker. plackup -s Starman --workers 1 -a app.psgi
I access /app1 and then /app2 in order. Both times the result is same "Hello App1".
But I access /app2 and then /app1 in order. Both times the result is same "Hello App2".
when I invoked app.psgi with 5 workers. plackup -s Starman --workers 5 -a app.psgi
Access to /app1 and /app2 many times, the Result is mixed. Access to /app1 returns "Hello App1" and "Hello App2" in random. Access to /app2 returns "Hello App2" and "Hello App1" in random.
I'm worry that mouting multiple webapps seems does not work.
I would try adding an appname to these codereferences: set appname => 'foo'; # Or similar If I recall correctly, the current app is stored by name, and with these both being unnamed they will clobber each other. I have multiple webapps working happily on the same Starman server, and they do not interfere with each other.
_______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
On Monday 13 June 2011 17:03:31 Alex Kalderimis wrote:
I'm worry that mouting multiple webapps seems does not work.
I would try adding an appname to these codereferences:
set appname => 'foo'; # Or similar
If I recall correctly, the current app is stored by name, and with these both being unnamed they will clobber each other. I have multiple webapps working happily on the same Starman server, and they do not interfere with each other.
Hmm - if that's the case, we should probably add a fix to generate a name for unnamed apps, either randomly making up a string, or just using a stringified hashref to get a unique key. (i.e., pseudocode, $apps{ $appname || {} } = $app;) -- David Precious ("bigpresh") http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
Hmm... 2011/6/14 Alex Kalderimis <alex@flymine.org>:
I would try adding an appname to these codereferences:
set appname => 'foo'; # Or similar
If I recall correctly, the current app is stored by name, and with these both being unnamed they will clobber each other. I have multiple webapps working happily on the same Starman server, and they do not interfere with each other.
I tried adding an appname and test it. But mounting multiple webapps does not work. This is my test code named test_multi_webapp.pl. ----------------------------------------------------------------------------------------- use WWW::Mechanize; use Test::More; my $starman_pid = "__starman.pid"; my $starman_workers = 2; my $repeat_count = 10; my $app1_url = "http://127.0.0.1:3000/app1"; my $app2_url = "http://127.0.0.1:3000/app2"; unless ( my $pid = fork() ) { system( "plackup --pid $starman_pid --port 3000 -s Starman " . "--workers $starman_workers -a multi_webapp.psgi " . ">/dev/null 2>&1" ); exit; } sleep 3; # wait until starman up my $mech = WWW::Mechanize->new(); $mech->get($app1_url); # first access is /app1 like( $mech->content(), qr/App1/, "Hello App1" ); foreach my $i ( 1 .. $repeat_count ) { $mech->get($app2_url); # continue access is /app2 like( $mech->content(), qr/App2/, "Hello App2" ); } done_testing; kill 1, `cat $starman_pid`; unlink $starman_pid; wait; exit; ----------------------------------------------------------------------------------------- And This is a webapps code named multi_webapps.psgi. ----------------------------------------------------------------------------------------- use Dancer ':syntax'; use Plack::Builder; my $app1 = sub { my $env = shift; set appname => 'App1'; get '/' => sub { return "Hello App1"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); }; my $app2 = sub { my $env = shift; set appname => 'App2'; get '/' => sub { return "Hello App2"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); }; builder { mount "/app1" => builder {$app1}; mount "/app2" => builder {$app2}; }; ----------------------------------------------------------------------------------------- My runtime environment is perl 5.8.9, Dancer 1.3050 and Plack 0.998. I execute a above test code with Starman's 2 workers and result is below(About half access was fail). $ perl test_multi_webapp.pl ok 1 - Hello App1 ok 2 - Hello App2 not ok 3 - Hello App2 (snip) ok 4 - Hello App2 not ok 5 - Hello App2 (snip) ok 6 - Hello App2 not ok 7 - Hello App2 (snip) ok 8 - Hello App2 not ok 9 - Hello App2 (snip) ok 10 - Hello App2 not ok 11 - Hello App2 (snip) 1..11 # Looks like you failed 5 tests of 11. What's wrong my webapps code ? Sincerely Yours. -- Takeshi OKURA
After looking into this I'm pretty convinced this is a genuine bug and that the root of it (no pun intended) is this code in Dancer::App which returns the handler for a request: sub find_route_through_apps { my ($class, $request) = @_; for my $app (Dancer::App->applications) { my $route = $app->find_route($request); if ($route) { Dancer::App->current($route->app); return $route; } return $route if $route; } return; } This checks all loaded apps for matching routes, regardless of the mountpoint they are associated with. For apps with prefixes, this will work, as they are prefix aware. But for side-by-side apps, apps will respond in a non deterministic manner due to the implementation of ->applications, which is a a values call on a hash, and if they respond to the same route (such as '/' in the test case) they will clash. I will see if I can submit a reasonable patch for this. Alex On Tue, 2011-06-14 at 15:57 +0900, Takeshi OKURA wrote:
use Dancer ':syntax'; use Plack::Builder;
my $app1 = sub { my $env = shift; set appname => 'App1'; get '/' => sub { return "Hello App1"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
my $app2 = sub { my $env = shift; set appname => 'App2'; get '/' => sub { return "Hello App2"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
builder { mount "/app1" => builder {$app1}; mount "/app2" => builder {$app2}; }; -- Alex Kalderimis Software Developer InterMine Cambridge Systems Biology Centre Tennis Court Road - CB2 1QR University of Cambridge ajk59@cam.ac.uk
I can get this test to pass with a small patch to Dancer::App (currently floating about as a pull-request on github) that privileges the current app so that routes are found appropriately. For reference the changes made and the test run are at: https://github.com/alexkalderimis/Dancer/commit/007fce0f487d3de7a79e01c17c73... Alex On Tue, Jun 14, 2011 at 11:41:35AM +0100, Alex Kalderimis wrote:
After looking into this I'm pretty convinced this is a genuine bug and that the root of it (no pun intended) is this code in Dancer::App which returns the handler for a request:
sub find_route_through_apps { my ($class, $request) = @_; for my $app (Dancer::App->applications) { my $route = $app->find_route($request); if ($route) { Dancer::App->current($route->app); return $route; } return $route if $route; } return; }
This checks all loaded apps for matching routes, regardless of the mountpoint they are associated with. For apps with prefixes, this will work, as they are prefix aware. But for side-by-side apps, apps will respond in a non deterministic manner due to the implementation of ->applications, which is a a values call on a hash, and if they respond to the same route (such as '/' in the test case) they will clash.
I will see if I can submit a reasonable patch for this.
Alex
On Tue, 2011-06-14 at 15:57 +0900, Takeshi OKURA wrote:
use Dancer ':syntax'; use Plack::Builder;
my $app1 = sub { my $env = shift; set appname => 'App1'; get '/' => sub { return "Hello App1"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
my $app2 = sub { my $env = shift; set appname => 'App2'; get '/' => sub { return "Hello App2"; }; my $request = Dancer::Request->new($env); Dancer->dance($request); };
builder { mount "/app1" => builder {$app1}; mount "/app2" => builder {$app2}; }; -- Alex Kalderimis Software Developer InterMine Cambridge Systems Biology Centre Tennis Court Road - CB2 1QR University of Cambridge ajk59@cam.ac.uk
_______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
Thank you Alex for solve my problem. I confirmed my problem was solved. But only "Dancer::App->set_running_app('App2');" is enough to solve my problem. patche was unnecessary for solve my problem. And I wondered that using any other word instead of 'App2' solved my problem. ex. Dancer::App->set_running_app('AppX') is solved my problem too. -- Takeshi OKURA
participants (5)
-
Alberto Simoes -
Alex Kalderimis -
Brian E. Lozier -
David Precious -
Takeshi OKURA