Showing posts with label psgi. Show all posts
Showing posts with label psgi. Show all posts

Thursday, June 8, 2017

How do I make a PSGI program do costly initialisation only once per process, not per thread?

Leave a Comment

cross-post: http://perlmonks.org/?node_id=1191821

Consider app.psgi:

#!perl use 5.024; use strictures; use Time::HiRes qw(sleep);  sub mock_connect {     my $how_long_it_takes = 3 + rand;     sleep $how_long_it_takes;     return $how_long_it_takes; } sub main {     state $db_handle = mock_connect($dsn);     return sub { [200, [], ["connect took $db_handle seconds\n"]] }; } my $dsn = 'dbi:blahblah'; # from config file my $app = main($dsn); 

Measuring plackup (HTTP::Server::PSGI: Accepting connections at http://0:5000/):

› perl -MBenchmark=timeit,timestr,:hireswallclock -E"say timestr timeit 10, sub { system q(curl http://localhost:5000) }" connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds connect took 3.0299610154043 seconds 2.93921 wallclock secs ( 0.03 usr +  0.06 sys =  0.09 CPU) @ 107.53/s (n=10) 

Measuring thrall (Starting Thrall/0.0305 (MSWin32) http server listening at port 5000):

› perl -MBenchmark=timeit,timestr,:hireswallclock -E"say timestr timeit 10, sub { system q(curl http://localhost:5000) }" connect took 3.77111188120125 seconds connect took 3.15455510265111 seconds connect took 3.77111188120125 seconds connect took 3.15455510265111 seconds connect took 3.77111188120125 seconds connect took 3.64333342488772 seconds connect took 3.15455510265111 seconds connect took 3.77111188120125 seconds connect took 3.85268922343767 seconds connect took 3.64333342488772 seconds 17.4764 wallclock secs ( 0.02 usr +  0.09 sys =  0.11 CPU) @ 90.91/s (n=10) 

This performance is not acceptable because the initialisation happens several times, despite the state variable. How do you make it so it happens only once?

0 Answers

Read More

Monday, April 4, 2016

Multi-site aware PSGI application development

Leave a Comment

The Plack::Builder allows mount multiple hosts, e.g. something as the following snippet:

my @sites = load_site_names(); my $apps; for my $site (@sites) {     $apps->{$site} = Some::PsgiFramework::MyApp->new( config => get_config($site) ); }  use Plack::Builder; builder {     for my $site (@sites) {         mount "$site" => $apps->{$site};     }     mount '/' => sub { ... }; } 

e.g.

  • the load_site_names returns a list of sites like http://example.com , http://some.other.site.com, ...
  • every "virtual-host" will use the same Some::PsgiFramework::MyApp
  • just their config is different

I need exactly the above - need develop one simple web-app which should be deployed for hunderts of different (low-traffic) sites and don't want setup an different PSGI server for each site.

However, the author of the Plack itself says (in the Plack::Request)

Note that this module is intended to be used by Plack middleware developers and web application framework developers rather than application developers (end users).

Writing your web application directly using Plack::Request is certainly possible but not recommended: it's like doing so with mod_perl's Apache::Request: yet too low level.

If you're writing a web application, not a framework, then you're encouraged to use one of the web application frameworks that support PSGI (http://plackperl.org/#frameworks), or see modules like HTTP::Engine to provide higher level Request and Response API on top of PSGI.

And this is the problem.

I checked many of different PSGI based frameworks in the MetaCPAN. And AFAIK each is singleton based, e.g. doesn't allows write applications which could be shared (mounted) many times for different sites in the same app.psgi.

So the questions are:

  • missed I something in the MetaCPAN (or in the docs), and here exists any (lighweight) web-framework which allows develop applications mountable many times in the app.psgi?
  • or i'm forced to develop Just Another My Own PSGI Framework? (To be honest, I not checked the catalyst - as it is too heavy-weight)
  • or just badly understand the "mounting"?

0 Answers

Read More