Re: [cgiapp] How to lazy-load runmodes

2011-05-23 Thread Ron Savage
Hi gvim

On Tue, 2011-05-24 at 04:15 +0100, gvim wrote:
> If I have a collection of, say, 15 fairly lengthy Perl scripts and I convert 
> them into a CGI::Application app with 15 runmodes isn't there a huge startup 
> penalty since my app must now load the code for all 15 runmodes prior to 
> dispatch? Is there a way to lazy-load my runmodes? Although I have each one 
> contained in a separate module I still have to 'use' all of them at once when 
> the app starts.

You don't have to use or load them all. If you adopt
CGI::Application::Dispatch and a MVC structure, only 1 controller module
gets loaded, and hence only the run modes in that module get loaded.

There are plenty of modules on CPAN which use this method.

Mine include App::Office::Contacts, App::Office::CMS,
Business::Cart::Generic and CGI::Application::Demo::Dispatch (hint).

Of course, if you run them under plack or Starman, they are permanently
resident anyway, so the startup overhead is only incurred once.

All the above modules include a plack/starman runner httpd/*/*.psgi
using C::A::D.

-- 
Ron Savage
http://savage.net.au/
Ph: 0421 920 622


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-23 Thread Joshua Miller
On Mon, May 23, 2011 at 11:15 PM, gvim  wrote:

> If I have a collection of, say, 15 fairly lengthy Perl scripts and I
> convert them into a CGI::Application app with 15 runmodes isn't there a huge
> startup penalty since my app must now load the code for all 15 runmodes
> prior to dispatch? Is there a way to lazy-load my runmodes? Although I have
> each one contained in a separate module I still have to 'use' all of them at
> once when the app starts.
>

Disclaimer - I haven't touched CGI::Application in over a year, and my last
go at it was to convert the product I'm currently supporting (~750,000 lines
of perl) to C:A, which never happened (got the framework in place, and had
disagreements internally on the template system, and the project went stale
- very sad). Anyway...

"isn't there a huge startup penalty..."
Not if you're using FastCGI, PSGI + something like FastCGI or mod_perl,
mod_perl, Starman or any other persistent perl thing. In those cases, it
loads and compiles once, and subsequent hits go to the compiled perl
bytecode (more or less). It's actually better and faster to have everything
loaded at first in these, so that memory is shared (COW for mod_perl under
linux). Under plain old bare-bones CGI, yes, there is a startup penalty on
every hit.

"Is there a way to lazy-load my runmodes?"
Yes. The exact details of that will depend on how you implement things, and
others here may have some recommendations. Lazy-loading modules will end up
breaking down to the following at some point in the code:

unless (eval "require $modulename") {
# handle the error. $@ will contain the error message.
}


In nearly all cases, the lazy loading won't be needed. If you're stuck with
running pure CGI, then it'll help some, but you'll get a lot more bang for
your buck by getting a provider or service running that supports mod_perl,
FastCGI, etc. Or, if you have a large or complex codebase, you might be
splitting off groups of functionality to different server clusters, and
those only need to have the modules loaded that are relevant to them... but
that's certainly not the case here.


Sorry... you were probably hoping for a drop in solution tailored to C:A
(and there may be one, but I don't know offhand) and I didn't help there,
and this is probably more info than you needed to hear.

If you have some info on what environment you're working with, I'm sure
someone can offer up some recommendations on a suitable persistent perl
server. Plack seems to be getting a fair bit of attention these days...
might want to start there (they have a long list of servers right on the
front page: http://plackperl.org/).

Hope that helps some,
--
Josh I.

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-24 Thread gvim
On 24/05/2011 05:27, Ron Savage wrote:
> Hi gvim
>
> You don't have to use or load them all. If you adopt
> CGI::Application::Dispatch and a MVC structure, only 1 controller
> module gets loaded, and hence only the run modes in that module get
> loaded.
>

But if I have only 1 controller module which 'use's 10 or 15 runmode modules:

use base 'AppBase';
use Register;
use Email;
use Another

  
sub setup {
   my $c = shift;
   $c->start_mode('register');
   $c->run_modes({
 register=> 'Register::register',
 email   => 'Email::email',
 another   =>  'Another::runmode',
 ...
   });
}

1;

... then I'm loading all 15 at startup, right? Even worse if I pack all those 
15 into subs without external modules as in a lot of examples on the CA website.

> There are plenty of modules on CPAN which use this method.
>
> Mine include App::Office::Contacts, App::Office::CMS,
> Business::Cart::Generic and CGI::Application::Demo::Dispatch (hint).
>
> Of course, if you run them under plack or Starman, they are
> permanently resident anyway, so the startup overhead is only incurred
> once.

But the memory footprint is still affected, surely? I'm just trying to weigh 
the benefits when running CGI::Application on a VM with a modest amount of 
memory.

>
> All the above modules include a plack/starman runner httpd/*/*.psgi
> using C::A::D.
>


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-24 Thread gvim
On 24/05/2011 06:23, Joshua Miller wrote:
> On Mon, May 23, 2011 at 11:15 PM, gvim  wrote:
>
> "isn't there a huge startup penalty..." Not if you're using FastCGI,
> PSGI + something like FastCGI or mod_perl, mod_perl, Starman or any
> other persistent perl thing. In those cases, it loads and compiles
> once, and subsequent hits go to the compiled perl bytecode (more or
> less). It's actually better and faster to have everything loaded at
> first in these, so that memory is shared (COW for mod_perl under
> linux). Under plain old bare-bones CGI, yes, there is a startup
> penalty on every hit.
>

Whilst a FastCGI solution improves startup time it doesn't address the memory 
footprint. I'm comparing deploying an app with CGI::Application vs. CGI with 
separate Perl scripts on a VM with a modest amount of mempory. From the what 
I'm learning about CGI::Application it seems that the memory footprint will 
skyrocket if your codebase has, say, 15 Perl scripts each containing over 300 
lines of code as you now have 15 x 300 lines of code running instead of 300, no?

gvim

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-24 Thread Michael Peters
On 05/24/2011 07:34 AM, gvim wrote:

> Whilst a FastCGI solution improves startup time it doesn't address the memory 
> footprint. I'm comparing deploying an app with CGI::Application vs. CGI with 
> separate Perl scripts on a VM with a modest amount of mempory. From the what 
> I'm learning about CGI::Application it seems that the memory footprint will 
> skyrocket if your codebase has, say, 15 Perl scripts each containing over 300 
> lines of code as you now have 15 x 300 lines of code running instead of 300, 
> no?

You're concerning yourself with irrelevant details until you know it's a 
problem. As Ron Savage pointed out earlier in the thread, if you split 
your run modes out into specific modules and then used C::A::Dispatch to 
dispatch between them then you'd basically have lazy loading.

But the key here is that you're worrying about memory usage before you 
know it's a problem. Perl abstracts a lot of the details about memory is 
used from you and any guesses you take about how much things will be 
will likely be wrong. 300 lines of code is nothing, memory wise. Data 
takes up a lot more space than code.

So my advice, write the application in a way that is the most 
maintainable and easy to adapt for the developers. Then do some 
profiling and find out if you are within your memory parameters and then 
(and only then, after you know it's a problem) do some memory tunings.

BTW, just some free advice from my experience: having a persistent 
(mod_perl, FastCGI, Starman, etc) environment will actually save you 
memory on linux. Forked processes will do copy-on-write (COW) memory so 
they will physically share the same memory even though logically they 
have their own memory space.

-- 
Michael Peters
Plus Three, LP

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-24 Thread Joshua Miller
On Tue, May 24, 2011 at 9:18 AM, Michael Peters wrote:

> On 05/24/2011 07:34 AM, gvim wrote:
>
> > Whilst a FastCGI solution improves startup time it doesn't address the
> memory footprint. I'm comparing deploying an app with CGI::Application vs.
> CGI with separate Perl scripts on a VM with a modest amount of mempory. From
> the what I'm learning about CGI::Application it seems that the memory
> footprint will skyrocket if your codebase has, say, 15 Perl scripts each
> containing over 300 lines of code as you now have 15 x 300 lines of code
> running instead of 300, no?
>
> You're concerning yourself with irrelevant details until you know it's a
> problem. As Ron Savage pointed out earlier in the thread, if you split
> your run modes out into specific modules and then used C::A::Dispatch to
> dispatch between them then you'd basically have lazy loading.
>
> But the key here is that you're worrying about memory usage before you
> know it's a problem. Perl abstracts a lot of the details about memory is
> used from you and any guesses you take about how much things will be
> will likely be wrong. 300 lines of code is nothing, memory wise. Data
> takes up a lot more space than code.
>
> So my advice, write the application in a way that is the most
> maintainable and easy to adapt for the developers. Then do some
> profiling and find out if you are within your memory parameters and then
> (and only then, after you know it's a problem) do some memory tunings.
>
> BTW, just some free advice from my experience: having a persistent
> (mod_perl, FastCGI, Starman, etc) environment will actually save you
> memory on linux. Forked processes will do copy-on-write (COW) memory so
> they will physically share the same memory even though logically they
> have their own memory space.
>
>

Completely agree and second this. If you have a choice of FastCGI or CGI,
just go FastCGI. If you're concerned about the differences in memory usage
and such, you're free to benchmark them, but I can assure you that, under
any load at all, FastCGI can serve more pages using less memory and cpu
time.

In my experience, mod_perl has been at least 10 times faster than CGI in
overall response handling time. Couple that with the COW memory savings, and
there's no going wrong here (though, with just 4500 lines of code, that's
not much to save... you will save on the other libs that get dragged in).

FYI, 300 lines of 72 characters times 15 == a file of 343 KB. If your env is
more limited than that, then you should probably be looking at C or assembly
:-)

The libs you use from your CGI script will pull in far more than that. As an
example:
$ expr 300 \* 15
4500
$ wc -l /usr/share/perl/5.10/CGI.pm
7885 /usr/share/perl/5.10/CGI.pm

--
Josh I.

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-24 Thread gvim
On 24/05/2011 19:08, Joshua Miller wrote:
>
> Completely agree and second this. If you have a choice of FastCGI or
> CGI, just go FastCGI. If you're concerned about the differences in
> memory usage and such, you're free to benchmark them, but I can
> assure you that, under any load at all, FastCGI can serve more pages
> using less memory and cpu time.
>

I just deployed the same app under CGI::Application::PSGI/nginx/Starman and I'm 
getting a weird error which is very difficult to debug. The app will run fine 
returning a results page from a database lookup but if hit the Back button and 
resubmit it will continue successfully for between 5 and 10 repetitions then 
fail on one of the app's error handlers for a for field having too many 
characters. So nginx has proxied successfully and Starman returns 200 but it's 
failing unpredictably.

I don't know if this has anything to do with it but I used a proxy_pass nginx 
setting rather than a fastcgi_pass setting.

gvim

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-24 Thread Ron Savage
Hi gvim

On Tue, 2011-05-24 at 20:28 +0100, gvim wrote:
> On 24/05/2011 19:08, Joshua Miller wrote:
> >
> > Completely agree and second this. If you have a choice of FastCGI or
> > CGI, just go FastCGI. If you're concerned about the differences in
> > memory usage and such, you're free to benchmark them, but I can
> > assure you that, under any load at all, FastCGI can serve more pages
> > using less memory and cpu time.
> >
> 
> I just deployed the same app under CGI::Application::PSGI/nginx/Starman and 
> I'm getting a weird error which is very difficult to debug. The app will run 
> fine returning a results page from a database lookup but if hit the Back 
> button and resubmit it will continue successfully for between 5 and 10 
> repetitions then fail on one of the app's error handlers for a for field 
> having too many characters. So nginx has proxied successfully and Starman 
> returns 200 but it's failing unpredictably.
> 
> I don't know if this has anything to do with it but I used a proxy_pass nginx 
> setting rather than a fastcgi_pass setting.

This is a completely different topic. You should have started a new
thread.

I don't run Apache anymore. I run nginx and proxy cgi-bin/ to
mini-httpd. A 'weird error' won't be in those programs, it'll be in your
code, no matter how hard you find that to believe :-))).

It's a classic symptom of using a global variable(s), although (of
course) it could be something else.

-- 
Ron Savage
http://savage.net.au/
Ph: 0421 920 622


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-25 Thread gvim
On 25/05/2011 07:37, Ron Savage wrote:
>
> I don't run Apache anymore. I run nginx and proxy cgi-bin/ to
> mini-httpd. A 'weird error' won't be in those programs, it'll be in your
> code, no matter how hard you find that to believe :-))).
>
> It's a classic symptom of using a global variable(s), although (of
> course) it could be something else.
>

It was a global variable :-). 'Trouble is it didn't show up when using 
Apache/CGI. Only when deployed with nginx + Starman. That's why I thought it 
was a Starman issue. I thought these global variable issues were only with 
mod_perl but they seem to apply to Starman though I couldn't find any 
guidelines about avoiding such issues with Starman. OK, I know you shouldn't 
use globals, and there was only 1 in this module, but if it's going to bork 
your app this badly it should be documented a la mod_perl. If globals are 
simply not an option rather than sloppy style it should be clearly stated.

gvim

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] How to lazy-load runmodes

2011-05-25 Thread Ron Savage
Hi gvim

On Thu, 2011-05-26 at 01:42 +0100, gvim wrote:
> On 25/05/2011 07:37, Ron Savage wrote:
> >
> > I don't run Apache anymore. I run nginx and proxy cgi-bin/ to
> > mini-httpd. A 'weird error' won't be in those programs, it'll be in your
> > code, no matter how hard you find that to believe :-))).
> >
> > It's a classic symptom of using a global variable(s), although (of
> > course) it could be something else.
> >
> 
> It was a global variable :-). 'Trouble is it didn't show up when using 
> Apache/CGI. Only when deployed with nginx + Starman. That's why I thought it 
> was a Starman issue. I thought these global variable issues were only with 
> mod_perl but they seem to apply to Starman though I couldn't find any 
> guidelines about avoiding such issues with Starman. OK, I know you shouldn't 
> use globals, and there was only 1 in this module, but if it's going to bork 
> your app this badly it should be documented a la mod_perl. If globals are 
> simply not an option rather than sloppy style it should be clearly stated.

It's not a problem with some specific web server. It's a problem with
persistent environments and carelessly-written programs...

I'd say it'd show up with Apache under load. In your test environment I
suspect the same process responds to every request, but under load the
global variable would be set in 1 process, but when another process
happens to respond, the variable is not set in /that/ process. Hence the
erratic behaviour under load.

-- 
Ron Savage
http://savage.net.au/
Ph: 0421 920 622


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####