Re: Mixing TOMCAT and mod_perl sessions

2002-08-12 Thread Perrin Harkins

Yair Lenga wrote:
 The website I'm supporting is running both TOMCAT applications ('.war'), 
 and has mod_perl scripts (all of them are registry - CGI scripts). I 
 have the following requirements:
 
 * The user identification information must be shared between TOMCAT
   and mod_perl (so that the user does not need to login twice).
 * No data sharing between mod_perl and TOMCAT application - but each
   of them need to store some persistent data.
 * Session should be persistent across server restarts (which
   excludes shared memory based solutions).

You would probably have to implement the session interface on both 
sides.  It could be fairly easy to implement sessions if you make a few 
assumptions, like a session will be a single hash with no complex 
structures or objects in it.  A simple serialization scheme would then 
be possible for both languages (maybe use an existing XML one).  You can 
use a database for persistent storage from both sides.

- Perrin






Re: [Newbie Q] Cleanest way to implement one logon per user?

2002-08-02 Thread Perrin Harkins

Eric Cholet wrote:

 Someone recently suggested to me the following solution, based on slightly
 modified sessions. It involves sending a cookie that contains a new ID 
 with
 each response. The server stores that ID keyed on the user's login name.
 The next request from the client is expected to return that
 cookie.


Sounds like an ordinary session to me.  If you aren't logged, you must 
log in.  Logging in clears all other sessions tied to this user ID. 
 That should work fine.

- Perrin




Re: [RFC] Apache::SessionManager

2002-08-02 Thread Perrin Harkins

Enrico Sorcinelli wrote:
 Apache::SessionManager creates an object session (in Header parsing phase, 
 but not obligatorily) and make it available to all other handlers 
 transparently by putting in pnotes. Others handlers can retrieve session
 directly from pnotes or by calling the simple function 
 Apache::SessionManager::get_session($r)

It would be better if you don't instantiate the session until someone 
asks for it the first time.  That will prevent unnecessary work.  Also, 
when using Apache::Session with any locking module except NullLocker, 
it's very important to have the session object exist for the shortest 
possible time because it is locking out all other access to that session 
while it exists.  (For this reason, it's also very important to make 
sure that requests for images and other static objects don't instantiate 
Apache::Session objects.)

 After some search on CPAN I haven't found a mod_perl module that does 
 the same thing (right?).

Some of the Apache::Auth* modules like Apache::AuthCookieURL are close, 
but I don't know of any that do the actual glue with Apache::Session. 
You might want to look at some of the existing modules and see if a 
merge of some kind is possible.

- Perrin




Re: [RFC] Apache::SessionManager

2002-08-02 Thread Perrin Harkins

Enrico Sorcinelli wrote:
Some of the Apache::Auth* modules like Apache::AuthCookieURL are close, 
but I don't know of any that do the actual glue with Apache::Session. 
You might want to look at some of the existing modules and see if a 
merge of some kind is possible.
 
 This modules haven't glue with Apache::Session

Right, that's my point.  Your module has overlap with them in terms of 
managing cookies and specifying locations, but adds the actual calls to 
Apache::Session.  If I were doing something like this, I would probably 
start with one of the Auth modules, which already do a good job of 
handling things like cookie verification and even cookie-less sessions, 
and add the actual Apache::Session glue.

It might at least be worth stealing some code from the other modules, 
like the ticket-based cookies idea, but of course you can do what you 
like.  I think it's good to have a module like this, and if you put 
yours out there people can contribute to it.  Incidentally there is also 
a session manager module very similar to this in the Extropia modules.

 I've written Apache::SessionManager to be used _also_ in a mod_perl handlers 
 or in a CGI script over Registry.

The Apache::Auth modules also support that.

- Perrin




Re: [RFC] Apache::SessionManager

2002-08-02 Thread Perrin Harkins

Enrico Sorcinelli wrote:
Incidentally there is also 
a session manager module very similar to this in the Extropia modules.
 
 
 Sincerely, I don't know Extropia modules!

You can find some documentation on them here:
http://www.extropia.com/support/docs/adt/customization.html#Session_and_Session_Manager_Conf

They're not on CPAN, so I'm not surprised you didn't see them.

- Perrin




Re: [Newbie Q] Cleanest way to implement one logon per user?

2002-08-01 Thread Perrin Harkins

Baljit Sethi wrote:
 What I want to do is limit client logons to one logon per username ie 
 while a client has a session open, he/she cannot logon to the website 
 from another terminal.

The simplest thing to do is create a new session for the user each time 
he logs in and invalidate any old sessions this user may have.  This 
assumes you are talking about actual logins, not just sessions for 
anonymous browsers.

- Perrin




Re: ANNOUNCE: Mason 1.12

2002-08-01 Thread Perrin Harkins

Dave Rolsky wrote:
 It can, but I'm not sure what to update it to.  Frankly, I think CPAN is
 more at fault here given that _many_ people use CVS for this sort of stuff
 and this quite normal when using CVS.

This is a common complaint about CPAN.pm, but it's kept this way so far 
because of performance issues with doing fancier version parsing.  I 
would suggest following David Wheeler's advice and setting version 
manually, so that you can just make 1.69 or something.

Incidentally, all hell is going to break loose when Perl 5.10 gets 
released.  Maybe that will force a change in CPAN.pm.

- Perrin




Re: [ANNOUNCE] Apache Hello World Benchmarks - Apache C API, HelloDB

2002-07-30 Thread Perrin Harkins

Dennis Haney wrote:
The bias in the test is even a little slanted towards the JSP
benchmarks since the trivial connection pooling I used there is
nothing like the Apache::DBI overhead in the mod_perl test, when I
could have just used a persistent global $dbh instead. ( maybe I
should? )
 
 
 I believe you should. It is the most common setup using mod_perl, if
 you are concerned about performance, anyway.

I think you got confused by the wording.  The most common setup with 
mod_perl is to use Apache::DBI, which is what he used in the test.

To answer the original question, I don't think Apache::DBI is much 
overhead at all.  It amounts to little more than a hash lookup. 
Certainly less work than the the thread synchronization required for 
connection pooling.

- Perrin




Re: [ANNOUNCE] Apache Hello World Benchmarks - Apache C API, HelloDB

2002-07-30 Thread Perrin Harkins

Josh Chamas wrote:
 My only problem with Apache::DBI for a benchmark is its
 default ping of the db per connect().

Oh, you're right I wasn't thinking about that.  It is important in a 
benchmark to be testing equivalent functionality as much as possible, 
although it's very difficult to do.

 I spent hours (  12 lines of code :) )
 writing an overly simple database connection pooling manager
 for the JSP benchmarks where a standard one seems to be
 lacking in JDBC  JNDI

I thought that JDBC had a pooling capability now.  I also thought Resin 
had something built in.  I would use those if possible.

Stick with Apache::DBI for mod_perl though.  I would never tell anyone 
to roll their own database persistence for performance instead of using 
Apache::DBI.  Pinging the database connection is good, and all systems 
should do it if they don't already.

- Perrin




Re: Apache-print Timed Out

2002-07-18 Thread Perrin Harkins

David Wheeler wrote:
  Why should Apache-print ever time out?

One reason could be a web client that disconnects.  There could also be 
a dropped network connection or one that's too slow.  I think you can 
adjust this behavior with the TimeOut directive in httpd.conf.

 I didn't even know that timing out was
 something that a print method could do.

This isn't the same thing as CORE::print.  It's overriden for mod_perl 
to send to the network.  Even CORE::print can return false in certain 
conditions, like when writing a file when the disk is full.

 And why does it only happen for some
 browser/platform combinations?

Probably buggy browsers or TCP stacks.

- Perrin




Re: [ANNOUNCE] Petal 0.1

2002-07-17 Thread Perrin Harkins

Rob Nagler wrote:
 Apologies to those who are tired of the *ML vs. Perl debate.

I think you're confusing the issue.  You're not talking about in-line 
Perl vs. templating languages, but rather templating vs. a whole 
different concept.

Jean-Michel clearly wants to use HTML-based templates, and wrote his 
module specifically for that purpose.  When most people talk about 
templates for web pages, this is what they have in mind: HTML (or XML or 
PDF or whatever) bristled with processing instructions in Perl or a 
templating language.  It's an easy transition for people who already 
know HTML, and provides what most people want from a templating solution.

What Bivio uses could reasonably be called a template, but it's a 
completely different animal from the sort of fill-in-the-blank 
templates that most people mean, and maybe deserves a different name. 
It's more like a declarative program, or a configuration file, or CGI.pm 
widgets.  It is an alternative to traditional templating, but suggesting 
that this will fix issues with XML parsing is kind of like saying you 
wouldn't need that winter coat if you lived in Hawaii -- true, but not 
very helpful to someone who lives in Montreal and likes it.

- Perrin




Re: Apache::Registry and Apache::PerlRun

2002-07-16 Thread Perrin Harkins

Boex,Matthew W. wrote:
 can i have both Registry and PerlRun running in the same environment?  i
 have my cgi scripts running under Apache::Registry in one directory, and
 want to run a legacy cgi script under PerlRun in another directory.  is this
 possible?

Yes, no problem at all.

- Perrin




Re: Purify, Perl and mod_perl

2002-07-16 Thread Perrin Harkins

Carwheel, Dan wrote:
 although their web page says only works for C, C++, Java and a few
 others, I've seen this page:
 
   http://www.perlpod.com/stable/perlhack.html 
 
 on getting Perl work with with Purify.

That page is about getting Perl's C executable to work with Purify, not 
using Purify to check your perl code.

 My question is this...can I run my application using this purified perl
 under mod_perl to track down potential memory leaks and other problems?

You probably don't have any memory leaks.  Most things that people refer 
to as leaks are just normal growth.  A leak is when an area of memory 
gets lost because the program that allocated it forgets to free it. 
Growth is when your program uses variables in such a way that it needs 
more memory over time.  The latter is pretty common.  Doing things like 
eval'ing code, reading variable length data into strings, and keeping 
other data structures that are affected by changes in user input or data 
over time will often lead to this.

If you have out-of-control memory growth, you should try finding it the 
old-fashioned way: take things out until it stops.  Then, if you find a 
little section that causes growth and you can't understand why, post it 
here and someone may be able to explain it.

A number of the most common sources of memory growth are explained in 
the guide: 
http://perl.apache.org/docs/1.0/guide/performance.html#Improving_Performance_by_Prevention

- Perrin





Re: sql-relay

2002-07-15 Thread Perrin Harkins

Richard Clarke wrote:
I came across http://www.firstworks.com/sqlrelay.html the other day. 
 Have any of you come across this product before.

It's been discussed here before (see the archives) but no one has talked 
about any real experience with it yet.  Try it out and tell us what you 
find.

  With the whole problem
 of providing seemless recovery at the client side from database 
 failure this tool seems quite productive.

What problem is that?  I don't think there's much you can do beyond 
re-connecting, which Apache::DBI does.

- Perrin




Re: TIPool / multiple database connections

2002-07-15 Thread Perrin Harkins

Elizabeth Mattijsen wrote:
 Hmm... but you won't be able to fetch the $dbh from the thread.  It 
 can only live in _that_ thread.  You cannot pass objects between 
 threads.  But you _can_ send queries to that thread, fetch a jobid for 
 that job and then obtain whatever was returned as a Perl datastructure.
 
 (if anyone knows of a way to pass objects between threads, I'd really 
 would like to know)

Hmmm... That could really throw a wrench in things.  If you have an 
object based on a hash, and you share that hash, and you re-bless the 
object in each thread, does that work?  What if the hash contains 
references to other variables.  Do they need to be explicity shared as well?

 Thread::Pool doesn't work that way.  You could have 1 database 
 connection in one worker thread and 40 threads submitting jobs: they 
 would be handled in the order they were submitted.  This effectively 
 serializes access (which could be an approach for DBI drivers that do 
 not support _any_ threading at all).

It could be useful for people who design their applications to use 
different database logins for each end user.  This would allow the 
server to maintain a single persistent connection to the database for 
that user, rather than one in each process.

 Or you could have 10 worker threads with 40 threads submitting jobs.  
 That would work faster if your database is threaded as well  ;-)

That would work well for the more common case, once the DBI threading 
issues are worked out.  But does this mean we would need to create a 
whole new interface for sending in queries and getting results back, 
because the actual $sth objects can't be shared?  That would be painful.

Maybe some kind of local proxy object could handle this, forwarding all 
method calls to the worker thread and returning all results.  It would 
be kind of like a transparent RPC mechanism.

- Perrin




Re: sql-relay

2002-07-15 Thread Perrin Harkins

Richard Clarke wrote:

 I mean in the case of the database crashing and being able to switch 
 to a replicated backup system.


That's trivial to implement if it happens during connect time.  You can 
simply keep a list of databases to try, and if one fails you go on to 
the next.  This approach is compatible with Apache::DBI, which will 
check database handles before handing them out to you.  It will attempt 
a re-connect, and if it fails it will pass the failure message back to 
you just as if it were a normal connection attempt.

It's harder if you want every query to be able to automatically retry on 
another database if it fails.  For that, you would need to add some 
extra code to catch the exception, recognize it as a connection failure, 
make a new connection, and retry the query.  I don't see anything on the 
SQL-Relay pages about this sort of ability.

- Perrin




Re: Propogating Errors / E-Toys

2002-07-10 Thread Perrin Harkins

Matt Sergeant wrote:
 On Wed, 10 Jul 2002, Fran Fabrizio wrote:
Just to confirm, the end result of Matt's slide presentation was that
Error.pm was good, and you should use it, but you should not use the
try/catch syntax, or at the bare minimum only catch in your outermost
handler.  Is that correct?  We were debating this just yesterday in our
office.
 
 Actually my recommendation for this year's talk on exceptions is to just
 use eval{}; if ($) {}. It's a little more typing, but at the end of the
 day closures created by subroutine prototypes are a really bad thing (tm).

I believe he was asking if Error.pm is a good class to use for 
exceptions if you don't use the try/catch keywords.  I think it is.  It 
provides handy methods for storing attributes of the exception and 
getting stack traces, and it's easy to subclass.  You could also use 
Dave Rolsky's Exception::Class, which is pretty similar.

- Perrin




Re: Growing Server Size modperl-2.0 on Solaris 2.7

2002-07-10 Thread Perrin Harkins

Stas Bekman wrote:
 If you are talking about threaded mpms, we will need to develop new 
 tools to restrict the size of the perl interpreters in the pool.

I was thinking about that too.  Are there hooks for causing an 
interpreter to exit?  Is it safe to simply call CORE::exit?  I'd like to 
make SizeLimit work for the threaded MPMs if possible.

- Perrin




Re: Growing Server Size modperl-2.0 on Solaris 2.7

2002-07-10 Thread Perrin Harkins

Stas Bekman wrote:
 I think the idea was to have a special thread running whose only purpose
 is monitoring the pool of idle interpreters.

That sounds like a better solution.

 I believe that we can add a Perl space hook that sets a flag that
 condemns an interpreter to death.

The other problem, which might be harder, is to figure out how big a 
particular interpreter is.  The current implementations of 
Apache::SizeLimit and GTopLimit cheat by asking the OS how big the 
current process is.  That won't work with threads.

- Perrin




Re: Propogating Errors / E-Toys

2002-07-09 Thread Perrin Harkins

Michael Schout wrote:

 in other words, if I understand the eToys article correctly, the leaks 
 only happen if I nest a try block inside another try block.  I have 
 experimented some, and it appears to me that this is in fact the case 
 ($count doesnt get cleaned up if there is a nested try).  But as long as
 I dont nest try blocks there doesnt appear to be a leak.


You are correct, you won't get a leak from the code in Matt's example. 
 What you will get is an unexpected persistence of the value of the 
$count variable.  It will retain its value and not be reset when you 
enter the handler sub again.

There are other problems too, like return not doing what you would 
expect when used inside a try block (it only returns from the try block).

- Perrin




Re: Perl sections

2002-07-08 Thread Perrin Harkins

Mike Blazer wrote:
MB Or may be there is some way to un-load mod_perl after Perl sections
MB processing?

If you need Perl sections only to do initial web server
configuration and you do not need mod_perl features in runtime then
instead of using Perl just write Perl script to generate Apache
config file from templates and run it before starting Apache. This way
you do not need mod_perl on frontend Apache at all.
 
 Yes, sure, that was my backup idea :) But I just wanted to make all 3
 configs in one big file, because of tons of the parameters (like log
 names, leves, auth, ssl etc). To keep it all together and start with -D
 proxy or -D pages.

Well of course you can do exactly that with what Ilya suggested: one 
template file that your script uses to generate appropriate conf files 
for each server.  It's really your only choice for a proxy server.  It's 
also somewhat safer, since it means your database doesn't have to be up 
just to start your proxy server.

- Perrin




Re: Understanding why this fixes my perlaccess script

2002-07-04 Thread Perrin Harkins

Jason Wilkes wrote:
 So far so good, and all works well. Except for one
 user id (actually id=333), which causes an internal
 server error. If I put print debugging lines in -
 everything works (even for user 333). If I take them
 out again all other users work fine except 333.
 Can anybody throw any light on this??

Yes.  You are returning the value of the last operation, 333, when 
$answer is not true.  To fix it, you should return DECLINED (or OK if no 
other access handlers should be allowed to run).

Why does it work when you debug?  Because you change the value of the 
last operation.

 BTW: when the internal server error happens there is
 no log of it in the error_log - although the HTTP
 response code in access_log is 333 (which I don't
 think is a valid response code).

There is no server error.  Your browser is just interpreting the 
response of 333 as a sign that something went wrong and putting a pretty 
face on it.  Microsoft browsers are notorious for this, although you can 
turn the behavior off.

- Perrin




Re: Propogating Errors / E-Toys

2002-06-30 Thread Perrin Harkins

Richard Clarke wrote:
 Using Perrin's article on E-Toys is perhaps a good place to start. In the
 Model object which performs various DB procedures, what actions were taken
 if for some reason the connection to the database failed or if an SQL error
 happened? Was the whole execute() block put in an eval procedure and then
 a generic error page produced; Or were either per procedure evals or
 Exception objects used to propogate specific errors up to the control object
 so that it could display errors in the current page/view?

Well, naturally the answer is it depends.  Most database errors can't 
be gracefully recovered from, so we would let them propagate up.  If it 
was possible for a database error to be caused by user input (say, a 
duplicate login name) that would need to be caught and handled.  It 
would also be caught if any special cleanup of non-database resources 
was needed.

Errors that propagate up are caught by an eval wrapping the whole 
handler method which issues a rollback to the database, logs the error, 
and prints either a pretty error page or a stack trace depending on the 
current debug settings.

Here's an excerpt from the documentation I wrote for our exception base 
class.  This uses the try/catch syntax from Error.pm.

=head1 HANDLING DBI ERRORS

Since DBI errors are the most common source of exceptions in our
application, I'm giving them special treatment here.  Because we are
planning to use the RaiseError option of DBI, you can expect DBI to
die whenever it hits a problem, as opposed to returning an undef value
that you have to check for.  This means that most of the time you
don't need to do anything special for handling DBI errors.  They will
propagate up and be caught at the top level.

DBI exceptions will be propagated as instances of the Error::Simple
class.

You can catch your own exceptions without catching the DBI
exceptions by catching specific classes other than Error::Simple.

   try {
   # lookup password in Oracle
   my $sth = $dbh-prepare_cached($sql_query);
   $sth-execute($bind_value);
   if (!$sth-rows) {
   # should have matched something
   throw ESF::Error::User::BogusPassword -text $password;
   }
   $ary_ref  = $sth-fetchrow_arrayref;
   # ... etc. ...
   }
   catch ESF::Error::User::BogusPassword with {
   # handle this error
   }; # -- don't forget!

It's okay to use transactions, and to put in your C$dbh-commit
statement at the end assuming everything will work.  If DBI throws an
exception that propagates to the top without being caught, we will
automatically issue a C$dbh-rollback command.

Sometimes, you may want to catch a specific DBI error.  Be careful
when doing this, because you need to know the error number or text of
the error message in order to trap the right exception.

DBI's raise error setting will cause it to fill the text attribute of
the Error::Simple objects it throws with the message given by Oracle,
so if you want to trap errors of type ORA-172, you can do this:

   try {
   my $sth = $dbh-prepare_cached($sql_query);
   $sth-execute($bind_value);
   }
   catch Error::Simple with {
   my $err = shift;
   if ($err-text() =~ m/ORA-172/) {
   # handle the error here
   } else {
   # let this error propagate
   $err-throw();
   }
   }; # -- don't forget!


- Perrin




Re: Propogating Errors / E-Toys

2002-06-30 Thread Perrin Harkins

F. Xavier Noria wrote:
 I remember the article has a comment regarding a gotcha of the Error
 module that causes memory leaks, but you didn't go into details there.

We've actually discussed this on the list.  It has to do with closures. 
  Matt gave a presentation about exception handling which covers it and 
shows a workaround.  You can see it here:

http://axkit.org/docs/presentations/tpc2001/

- Perrin




Re: Need Porting Sanity Check

2002-06-29 Thread Perrin Harkins

Jeff wrote:
 Hey thanks for the reply.  I am making progress but I have run into a
 problem where when I have PerlRun enabled my scripts are not see the
 field values being passed in the URL.  I'm still using cgi-lib.pl not
 CGI.pm.

I've never used cgi-lib.pl and you shouldn't either.  That package has 
been deprecated for many years.

 By the way, do you know if PerlRun caches CGI.pm because I know
 otherwise it takes longer to load than the old cgi-lib.pl

CGI.pm -- and any other external modules you use -- will be cached when 
used from PerlRun.  The only thing that isn't cached is your script itself.

- Perrin




Re: Need Porting Sanity Check

2002-06-29 Thread Perrin Harkins

Jeff wrote:
 So here is my strategy that I would like a sanity check from anyone on.  
 Go through and quickly clean up my existing code by adding use strict 
 and localizing all my variables (with 'my' and 'local' for special 
 variables) and then run is under mod_Perl using the Apache::PerlRun.  
 Write all my new code so that it will run under Apache::Registry and 
 then when I have spare time (ya right) go work on porting the older code.

PerlRun works reasonably well, and I have used it to quickly port a 
large amount of legacy CGI code that made extensive use of globals. 
However, it is only very slightly different from Apache::Regsitry.  The 
difference is that globals get cleared after each invocation, so you 
don't have to worry about them retaining values.

You will not have problems with subroutines creating closures if you're 
using global variables.  You also won't have problems if you're passing 
varaibles to subroutines.  You will only have trouble if you use 
lexicals in your subs that are defined outside the scope of the sub.

This is bad:

my $foo = 7;
print_foo();

sub print_foo {
 print $foo\n;
}

But this is not:

my $foo = 7;
print_foo($foo);

sub print_foo {
 my $foo = shift;
 print $foo\n;
}

One thing that I had to change when moving to PerlRun was that the 
existing scripts made extensive use of libraries that were not proper 
modules, i.e. they did not declare packages, but just used a simple 
require lib.pl to define a bunch of stuff in the current namespace. 
That doesn't work with PerlRun or Registry.  There are various 
approaches for dealing with this, the quickest and worst being to change 
the require file to a do file.  The best is to make them actual modules.

- Perrin




Re: Any known good configuration for mod_perl DSO?

2002-06-27 Thread Perrin Harkins

Wilbur, Charlton wrote:
 Or am
 I looking at rolling my own RPMs or installing from source RPMs?  My
 suspicion, confirmed by Mr Turner, is that this is tied directly to shared
 libraries and toolchains, and so I suspect further that the problem will go
 away if I build everything from scratch using source RPMs.

I highly recommend building your own RPMs.  It works great, you get 
exactly what you want (and nothing you don't want), and you can install 
them quickly on a cluster of machines because you don't have to 
recompile on each one.

- Perrin





Re: missing .al files with apache/mod_perl

2002-06-26 Thread Perrin Harkins

Allen Day wrote:

Furthermore, this file doesn't exist in my filesystem.  How is it possible
that (1) the module works without this apparently required file at the
command line but (2) doesn't work with apache/mod_perl ?


How is it possible?  Two ways: you could be wrong about the existence of 
the file, or the situtation that requires the file might only arise when 
you use it with mod_perl.  I'd suggest you start debugging it by looking 
at the things that are different when running it from mod_perl: the 
user, environment variables, working directory, ways that you call it, 
etc.  One of those things is probably responsible.

- Perrin




Re: when to mod_perl?

2002-06-25 Thread Perrin Harkins

md wrote:
 I was just a bit worried about the amount of static
 content. In the past I've had a lot more hardware to
 work with and I never had to worry about it much.

Static content is easy; just don't serve it from mod_perl.  The proxy 
approach is good, and so is a separate image server (which you can host 
on the same machine).  I've found thttpd to be an amazingly efficient 
server for images, but a slimmed-down apache does very well too.

- Perrin




Re: mod_perl memory leaks on Windows

2002-06-25 Thread Perrin Harkins

Andrey Prokopenko wrote:
 After a fresh restart, I started Apache/mod_perl. Then i issued a
 little stress test using simple perl script with LWP::Simple.
 I ran a performance test on /mod_perl/index.pl page for 10 minutes. The
 source code of that page is given below :
 -
 #!/perl/bin/perl
 use CGI qw(:all);
 
 print header;
 print Hello, World!; 
 -
 After 10 mintues of execution, the memory consumption of Apahce.exe
 had jumped from approx 5 MB to 120MB ( virtual memory ).
 I ve noticed, that Apache child grown by 4-8kb per each request.

Have you tried it without using CGI.pm?  Have you tried writing a 
handler instead of using Apache::Registry?

 I know that mod_perl on Windows is a development version but still
 this memory leak thing is pretty obvious and should have been taken
 care off.

There's a pretty good chance that it's not mod_perl causing it.  It may 
be just that Win32 perl grows a little when you run that CGI::header 
call over and over.

The upcoming mod_perl 2 will have better support for Windows.  You can 
find information on it here:  http://perl.apache.org/release/docs/

- Perrin





Re: mod_perl memory leaks on Windows

2002-06-25 Thread Perrin Harkins

Andrey Prokopenko wrote:
 I tried a plain Perl cgi script, with no module used, and still the
 same. ;((
 Do you mean that this leak cannot be fixed from Apache/mod_perl side ?

I can't say for sure since I don't use mod_perl on Win32, but most of 
the process growth problems reported when using mod_perl are not caused 
by mod_perl.  They are usually caused by the perl code involved, but it 
looks like a mod_perl problem because when running under CGI you never 
get the chance to notice this growth (because the processes are not 
persistent).

 Sorry, but for now we're stuck with Apache 1.3.x, because we use module, which
 cannot work with Apache 2.0. So i seek appropriate solution based on
 Apache 1.3 version.

Why can't the module work with Apache 2?  You might be able to get some 
advice here on how to fix it.

Otherwise, you could look at alternatives like PerlEx, but they may have 
the same issues.

- Perrin




Re: [ANNOUNCE] Apache::DBI 0.89

2002-06-21 Thread Perrin Harkins

Stas Bekman wrote:
 the threaded mpms will need a new version/mode of Apache::DBI using 
 threads::shared, currently available only for 5.8.0-tobe, unless things 
 will get backported to 5.6.2. Currently it seems that the threaded mpms 
 will be safe to use only with 5.8.0, unless again things will get 
 backported. Otherwise chances are that 5.8.0 will be a requirement.

I saw that message, which is why I mentioned 5.8, but I was wondering if 
anyone has seen discussion of whether or not DBI will be safe to use 
with 5.8 threads.  Does anyone know?

- Perrin




Re: XML::Write and XML::Simple incompatibility

2002-06-20 Thread Perrin Harkins

Prakash Chatterjee wrote:
 Thanks people.
 
 It turned out to be an Expat problem. As advised, we compiled Apache without
 EXPAT - and hunky dory - it works.

Sorry about that, I steered you wrong: it was a mod_perl/apache problem. 
  I know about the Expat issue, but I didn't think either of those 
modules would work if you had this problem and it sounded like you were 
only getting it when trying to use both of them together.

- Perrin




Re: Apache::LightBackhand

2002-06-20 Thread Perrin Harkins

Ricardo Basto wrote

I'd like some feedback on this module I just wrote. It's something like a
reverse proxy, but intended as a gateway from the fully-functional
apache/mod_perl to another webserver, probably behind a firewall in the
corporate network.
  


That sounds just like mod_proxy's reverse mode or several of the 
mod_perl proxy modules on CPAN.  Have you looked at those?  Also, the 
name is confusing because it doesn't seem much like mod_backhand.

Don't get me wrong, the code looks fine and it's nice of you to make it 
public.  I wouldn't suggest putting it on CPAN though unless it does 
something that the others don't do.

- Perrin




Re: separating C from V in MVC

2002-06-18 Thread Perrin Harkins

Tony Bowden wrote:
 I'd have to disagree. Maybe Mike had something different in mind when he
 created Class::DBI, but as the current active developer on it, I'm
 definitely pushing it in the R-O direction. Like Dave, I always start by
 thinking of my database schema and then Class::DBI provides a way to
 translate that, table - class, row - object, column - method. Throw
 in some simple relationship builders and a sprinking of syntactic sugar,
 and that's pretty much there is to Class::DBI.

Tangram may have loftier goals, but in general that's pretty much all 
there is to any of them.  And I don't think that the angle you approach 
your data design from -- classes or tables -- has much bearing on which 
tool you would use, with the possible exception of Tangram.  SPOPS is 
explicit about wanting to support legacy schemas without changes.

I think that in this realm there is Tangram, which tries to bring some 
extra stuff like database modelling of object inheritance and queries 
written in perl, and everything else.

Things like Tangram model the domain objects, i.e. concerts,
seats, people.  Things like Alzabo model the database objects, i.e.
tables, rows, foreign keys.
  
 I think on this front they both try to do both. Class::DBI does anyway.

My casual perusal of the documentation certainly made it look like 
Class::DBI hid a lot more of the database stuff than Alzabo.  After the 
configuration is done, the database concepts like foreign keys are never 
explict.

I guess my point here is simply that I think there isn't so much 
difference between most of these tools and that characterizing them as 
being anti-database or too heavy is not accurate.

As a sort of wrap-up to this round of O/R technology discussion, I want 
to post a link to this quote from the author of SPOPS where he talks 
about the practical limitations of SQL abstraction.  I thought it was a 
pretty astute observation:
http://perlmonks.org/index.pl?node_id=162259

- Perrin




Re: [RFC] Change our habits in module naming?

2002-06-16 Thread Perrin Harkins

 Also, a module map might be a good thing to create, i.e. an improved
 version of this: http://perl.apache.org/src/apache-modlist.html.

 Well, because the module list has now moved into the Perl Module List
 entirely, we are removing it with the new site.

What I meant was that since you can't expect all of the existing modules
to change their names you could make a little directory page that
follows the organization you're proposing and have it list the existing
modules in each category.  Maybe not worth it, but it could be useful
for newbies.

- Perrin




Re: MVC Topic Joy

2002-06-15 Thread Perrin Harkins

 In most cases the Handler is set to view, in which case View.pm
 instantiates other modules objects, (and those instantiations use
other
 url string data to determine what to construct into the object). View
 then just spits out the default head, body (created with the other
 objects) and footer.

 All of the real work is done by the other modules. View.pm could
care
 less what comes back from $html_obj-view_data. It just adds the
result
 to $body. It's the html module's job to fill the return from view_data
 with the correct information.

It sounds like you have a system that works well for you, and that's
what really matters.  I would probably try to get this default HTML that
View.pm puts out into the same place the rest of your HTML is created,
especially since it seems like View.pm is responsible for interpreting
request data and calling methods on model objects.  (View.pm is maybe a
somewhat misleading name, since it isn't the part that generates the
HTML view.)

- Perrin




Re: [OT] WebObjects [Was: Re: separating C from V in MVC]

2002-06-15 Thread Perrin Harkins

 WO is amazing, no two ways about it.  Once you use it, everything else
 sucks.  There are no exceptions.

That's kind of a rude statement to make on this list, where all of these
people are offering free software and support to you.

It's been a few years since I last evaluated WebObjects, but it
certainly didn't seem like a panacea.  It had a number of interesing
ideas behind it, but its insistence on trying to hide all the details of
the browser interaction made some simple things very hard, especially
since it tried to keep all of the state information server-side.  The
problems it had with back buttons and multiple browser windows come to
mind.  It also seems to encourage design where browsers directly request
a view, rather than calling a controller which chooses a view depending
on the outcome of processing.  That could be just a shortcoming of their
introductory documentation though.

- Perrin




Re: separating C from V in MVC

2002-06-15 Thread Perrin Harkins

 My general motto is tiers eq tears ... I've never seen
 a really comfortable OO/SQL bridge.

So who's talking about an OO/SQL bridge?  Not me.  At least not an
automatic one.  I write the SQL by hand.

 Group bys, order bys, multi-table selects, locking, SQL query
 plans and index optimisation all rightfully belong to the database but
are
 an anathema to a simple OO/SQL bridge.

I use all of those things in my model objects.  The model objects use
SQL to implement methods like $product-user_comments() or
$address-save(), and sometimes it is complex.  The point is that the
rest of the application gets to the database through the model objects,
rather than through SQL.  Encapsulation, reuse, blah blah blah.

 Generally I try to minimise the layers/tiers/abstraction between
 the front-end and the database - for me OO/SQL abstraction is
something
 akin to 'GOTO considered harmful'.

I think you're overgeneralizing based on some kind of O/R mapping tool
you've used that tried to do too much.  Wrapping up the knowledge of how
to work with the database to accomplish certain tasks inside of objects
is no different from any other application of OO programming.

- Perrin




Re: separating C from V in MVC

2002-06-15 Thread Perrin Harkins

 This approach works for some things, but I think it falls down when it
 comes to doing complex database searches, particularly searches
generated
 ad-hoc on multiple columns in multiple tables.

In general, the user interface you provide for a search will be much
higher-level than the SQL that implements it.  That's what is gained by
making this kind of object: it's a place to put the translation of the
business concept find people in New Jersey into the four table join
that might be needed to find them.

 This is why Alzabo is much lower-level than what you have above.  I
needed
 something where I could easily construct queries that might include 1+
 tables, with various types of searches of individual columns in those
 tables (equal to, between, less than, like, etc.) with dynamic sorting
 (again, on any of the columns in any of the tables, ascending or
 descending).

I would just write SQL at that point, but I do realize that Alzabo
provides more database independence.  You could easilly use Alzabo to
build the queries that implement the model objects I'm talking about.

 With what you're proposing, I think you could easily end up with
either:

 A) a ridiculously flexible interface that looks sort of like SQL,
except
 where it is SQL, except where it's only sort of like SQL, etc.

 B) a ridiculous profusion of classes, methods, or both.

I think you're overestimating the number of search variations and model
objects that most applications have.  For example, Fran's application
generates his stale watches report.  There's no need to create a
fully-parameterized search interface to Watch objects just for that.
Instead, you make a Watches-find_stale() method or something and keep
the knowledge of what that means to the database hidden behind that API.

At eToys we had a very large and complex (highly normalized) database,
and this approach worked very well.  I think it works best when you have
a complex database requiring complex SQL, because if you just have a
bunch of simple 1-1 table mappings there isn't really much to abstract.

I'm thinking of trying out SPOPS the next time I do this kind of thing,
because it will automatically handle the no-brainer cases (1-1 mappings)
and allow me to write the SQL for the complex cases by hand, all with a
consistent interface and hooks for caching, etc.

 Trying to jam a thick layer of OO-goodness over relational data is
asking
 for a mess.  OO has its place, but if your application is primarily
about
 the database, I don't think that a heavy OO layer on top of that will
do
 you much good.

There's nothing thick or heavy about the way I do it.  There is no
automatic SQL generation, and nothing to prevent me from using any SQL
tricks that my database supports.  It's just a way of wrapping up chunks
of code that implement data-related tasks into an easy task-oriented API
for the controller (or other model objects) to act on.

- Perrin




Re: separating C from V in MVC

2002-06-15 Thread Perrin Harkins

 An Object-Relational mapper takes objects and stores them in a
relational
 database, as transparently as possible.  I think the most pure example
of
 this I've seen in the Perl world is Tangram
(www.tangram-persistence.org).
 SPOPS is also an O-R mapper (actually, its a generic Object
persistence
 mechanism but it seems to most feature-rich when used with an RDBMS).

 A Relational-Object takes a relational database, and provides access
to it
 (select, insert, update, delete) via objects.  Class::DBI, Alzabo, and
 DBIx::RecordSet are examples of such a beast.

I would actually put Class::DBI in with the first set.

To me the difference is not O/R vs R/O, since both of them go both
directions.  Rather it's a question of what you're modelling in your
objects.  Things like Tangram model the domain objects, i.e. concerts,
seats, people.  Things like Alzabo model the database objects, i.e.
tables, rows, foreign keys.

My approach falls in the first camp, although I don't currently use any
OOP tools for assistance.

- Perrin




Re: [OT] WebObjects [Was: Re: separating C from V in MVC]

2002-06-15 Thread Perrin Harkins

 Not quite sure what you mean here.  The general WO request-response
loop is
 1 Process request
 2 Perform action
 3 Return response

 Step 3 is entirely dependent on the previous two, just like any
 mod_perl/CGI/php app.

The introductory documentation makes it look each URL is tied to a
specific HTML template.  It may just be a problem with that
documentation though.

 I think the most perfect web
 development env would be a WO-style framework build on top of mod_perl

You can assemble various parts of it from CPAN.  Most of the perl O/R
frameworks are not as ambitious as EOF, but Tangram is trying pretty
hard.  The templating tools available for perl are as good as the ones
in WO.  Using those with one of the MVC frameworks discussed here gets
you quite a bit.  The main thing you don't get is GUI tools, which there
doesn't seem to be much demand for from the mod_perl community.

- Perrin




Re: [OT] what drives Amazon?

2002-06-15 Thread Perrin Harkins

 Does anybody know which is the technology behind Amazon?

If you look at their job listings, you'll see it's a lot of C/C++ and
Perl, with a smattering of other things, running on Unix.  That's pretty
typical of the really big sites.

- Perrin





Re: Mapping to location /

2002-06-13 Thread Perrin Harkins

md wrote:
 What I'm really trying to do is more like the PHP I'm
 replacing. I should be able to go to:
 
 www.someserver.com/index.phtml for a dynamic page 
 and
 www.someserver.com/index.html for a static page.
 
 I'm guessing that my best solution would be to use
 HTML::Mason or Apache::ASP instead of
 Template-Toolkit.

Why?  Just because you don't have literal files for those URLs with TT 
and with Mason or ASP you would?

I don't really see the problem.  You can map all the URLs that end with 
a certain extension to one module that does some work and then calls a 
template.  You can map individual URLs or sets of URLs to separate 
modules that do different processing and call a template.  You could 
even put the actual files there and use Apache::Template to serve them. 
  Apache::Template has a hook to add your processing code before the 
template gets run, and you can have multiple handlers that do different 
processing in different locations.

 I may try using the PerlTransHandler to change the uri
 to a location...say with
 www.someserver.com/index.phtml the uri gets changed to
 /modperl (or www.someserver.com/somedir/index.phtml
 the uri becomes /modperl/somedir) which is used in a
 Location /modperl directive.

What does that get you?  I don't see why you would want to do that.

- Perrin




Re: separating C from V in MVC

2002-06-13 Thread Perrin Harkins

Fran Fabrizio wrote:
 Now, how do you represent in the model a
 complex query that joins across 5 of the nouns?

Others have already commented on this, but I want to point out that this 
is a general OO modelling question, not an MVC one, and there are many 
resources available to help you learn this stuff.  I'd suggest getting 
to your local computer book store and browsing through some OO 
programming titles.

 In your concert example, if I wanted to define a report that showed me 
 all of the seats that were purchased by people from New Jersey with a 
 Mastercard in the last week, how would I represent that?

That's a tricky one, because it doesn't make much sense to put all that 
logic about finding users' home states and payment types into a Concert 
class.  You could manipulate the objects to accomplish this:

my wanted_seats;
my seats = Model::Concert-findSeatsReservedAfter($date);
foreach my $seat (seats) {
 if ($seat-person()-address()-state() = 'NJ') {
 push wanted_seats, $seat;
 }
}

As you can see it gets messy fast, and I didn't even cover the 
Mastercard part.  It would probably have terruble performance too.  This 
is why people usually just write this kind of report as a big SQL query 
instead.  You can make a model object called ConcertSeatSearch:

seats = Model::ConcertSeatSearch-findSeats(
  reserved_after = $date,
  payment_type   = $card,
  user_state = $state,
 );

Just be careful that you don't end up making this into something that 
mirrors the SQL exactly.  There might be 4 tables involved in finding 
out what kind of credit card the user had, but that gets hidden behind 
this API.  If you find yourself writing classes that take options like 
where = 'date  ' . $date you are reinventing SQL, and you've lost 
your abstraction.

- Perrin




Re: mod_perl/passing session information (MVC related, maybe...)

2002-06-13 Thread Perrin Harkins

Rob Nagler wrote:
A session is useful for very limited things, like remembering if this 
user is logged in and linking him to a user_id.
 
 
 We store this information in the cookie.  I don't see how it could be
 otherwise.  It's the browser that maintains the login state.

My preferred design for this is to set one cookie that lasts forever and 
serves as a browser ID.  If that user logs in, you can associate a user 
ID with that browser ID, on the server side.  You never need to send 
another cookie after the very first time someone hits your site.  If you 
decide to attach new kinds of state information to the browser, you 
still don't need to send a new cookie.

Many sites need to keep track of state information (like what's in your 
shopping cart) for anonymous users who haven't logged in.  Having this 
unique browser ID (or session ID, if you prefer to give out a new one 
each time someone comes to the site) lets you track this for 
unregistered users.

 Consider the following scenario:
 
 * User logs in.
 * Site Admin decides to delete the user.
 * In our stateless servers, the user_id is invalidated immediately.
 * Next request from User, he's implicitly logged out, because the user_id
   is verified on every request.
 
 In the case of a session-based server, you have to delete the user and
 invalidate any sessions which the user owns.

I don't see that as a big deal.  You'd have to delete lots of other data 
associated with a user too.  Actually deleting a user is something I've 
never seen happen anywhere.

Although Oracle can be fast, some data models and application 
requirements make it hard to do live queries every time and still have 
decent performance.  This is especially true as traffic starts to
climb.
 
 
 I've tried to put numbers on some of this.  I've never worked on a
 1M/day site, so I don't know if this is the point where you need
 sessions.  What sites other than etoys needs this type of session
 caching?

Well, eToys handled more than 2.5 million pages per hour, but caching 
can be important for much smaller sites in some situations.  It's not 
session caching necessarilly, although we did cache session data in a 
local write-through cache on each server.

We knew that the database would probably be the bottleneck in scaling 
our application, and it was.  We took pains to take as much work as 
possible off the database, so that it could spend its resources on 
handling things that can't be cached, like user submitted data and orders.

Here's a situation where a small site could need caching: suppose you 
have a typical hierarchical catalog site, with a tree of categories that 
contain products.  Now suppose that the requirements for the site make 
it necessary to do a pretty hairy query to get the list of products in a 
category, because you have some sort of indirect association based on 
product attributes or something and you have to account for start and 
end dates on every product and various availability statuses, etc. 
Categories should only be shown if they have products in them or if 
their child categories have products in them.  Keep piling on business 
rules.  Then the UI design calls for the front page to have a 
Yahoo-style display showing multiple levels of the category hierarchy, 
maybe 70 categories or so.

Sure, you get your DBAs to tune the SQL and to put all the indexes in 
place, and it gets the results for a single category pretty fast, in .08 
seconds, but you have 70 of them!  When you throw multiple users in the 
mix, all executing these queries every time they hit the homepage, your 
database server will burn a hole through the floor.

Or you can take advantage of your domain knowledge, that the data used 
in generating this page only changes every 6 hours or so, and just cache 
the page, or part of the page, or the data, for an hour.

Maybe I just have bad luck, but I always seem to end up at companies 
where they give me requirements like these.  And then they say to make 
it really fast and handle a billion users.  They are happy to trade 
slightly stale data for very good performance, and part of the 
requirements gathering process involves finding out how often various 
kinds of data change and how much it matters if they are out of date. 
(For example, inventory data for products changes often and needs to be 
much more current than, say, user comments on that product.)

- Perrin

- Perrin




Re: mod_perl/passing session information (MVC related, maybe...)

2002-06-12 Thread Perrin Harkins

Vuillemot, Ward W wrote:
 There is a Apache::Session which is sufficient to check to see if they are
 logged in, et cetera.
 But I want to be able to remember the last query so that I can return
 results into multple pages along with memory of where in the stack I am at.

You can store anything in Apache::Session; it's just a persistent hash 
table.  However, storing query results based on a user's session is not 
a good idea!  What if your users open up two browser windows and tries 
to do a search in each one?  Server-side session data is global to all 
browser windows, so they'll get bizarre and incorrect results.  If you 
check any of the major sites you'll see that they handle multiple 
windows correctly.

My suggestions would be to have a separate cache just for query results. 
  Turn the sorted query parameters into a key.  If someone goes to page 
2 of the results, you just pull them out of the cache.

 There are persistent modules, but I am wondering if there is a better way
 with Apache and mod_perl

There have been a few benchmarks of ways to store a persistent hash. 
I'll have some new numbers on this soon, but for now I'd suggest looking 
at Cache::Cache, MLDBM::Sync, or Cache::Mmap.

- Perrin





Re: mod_perl/passing session information (MVC related, maybe...)

2002-06-12 Thread Perrin Harkins

Jeff AA wrote:
 Agreed, but he wasn't talking about storing the results, just the query
 parameters and current offset / number of rows, which is a-ok for
 putting into a session.

No, that's exactly what ISN'T okay for putting into a session.  If a 
user opens two browser windows, does a search in each, and then pages 
forward in each set of results, he will get completely wrong pages if 
you do this.  The query parameters from the first search will be written 
over and lost.

 Don't forget that you can have multiple sessions - store the query
 params in a session identified by a query_id so that subsequent requests
 just say something like: A
 HREF='/searchquery_id=123456789action=next'Next/A

You could do that, with a unique ID for each set of parameters, but you 
might as well just put the parameters right in the link unless they're 
very long.

 Don't mix transient query sessions with a User Session that stores info
 about the user's logged in state etc. It would be normal for one user to
 have multiple queries in a login session

Hold on, I think we actually agree, but you're using the word session 
for a bunch of different things.  What you're saying here sounds like 
the opposite of what you said above.  In common usage, a session is the 
state of the user's interaction with the application.  A cache of query 
data would be something else.

 Or even to use a database that has a decent approach to caching. MySQL
 promises automatic cacheable paged queries in the near future. And if
 you write your own DB cache, you then need to manage the DB / cache
 synch issues, cache size, cache expiry etc etc issues. Good cache is
 very hard to do! better to get it from a real data bank.

MySQL is fast, but usually not as fast as simple disk access. 
Cache::Cache and Cache::Mmap handle the details of the cache stuff for 
you, making it pretty easy.

- Perrin




Re: mod_perl/passing session information (MVC related, maybe...)

2002-06-12 Thread Perrin Harkins

John Siracusa wrote:
 On 6/12/02 12:57 PM, Per Einar Ellefsen wrote:
 
But what if someone opens one of the links in a different window, and
continue on the same pages as in the original window, but with different
parameters? The session ID would be the same, the context id would be the
same, but the params would be different, right?
 
 
 Well, then things break I guess... :)  Maybe you could do some magic based
 on what browsers send as the referrer when users explicitly open a link in a
 new tab or window?  Probably not worth it...

Right, which is why you shouldn't try to store server-side state for 
anything that could be different in multiple browser windows.  Only 
store global browser information on the server-side.  Everything else 
has to go into the links and forms.

- Perrin




Re: mod_perl/passing session information (MVC related, maybe...)

2002-06-12 Thread Perrin Harkins

Rob Nagler wrote:
 Stateful instances are also problematic.  You have essentially two
 paths through the code: first time and subsequent time.  If you write
 the code statelessly, there is only one path.  Fewer bugs, smaller
 code, less development.

I find you can tie this cache stuff up inside of your data access 
objects and make it all transparent to the other code.  That worked 
really well for me.  There are hooks for this in some of the O/R mapping 
modules on CPAN.

 Sessions are caches.

One of the things Java programmers often do wrong is cache general data 
in the session, because the servlet API makes it so easy to do.  But 
most data that people cache (as we're seeing in this discussion about 
search params) is not user-specific and thus doesn't belong in the 
session (i.e. everyone who searches for foosball gets the same result).

A session is useful for very limited things, like remembering if this 
user is logged in and linking him to a user_id.  Almost everything else 
belongs either in separate database tables or in the query args passed 
on each page.

 Oracle will cache the query compilation and results so it is very fast
 (basically a round-trip to database server) for the second query.
 We execute these two queries on every paged list on every request.

Although Oracle can be fast, some data models and application 
requirements make it hard to do live queries every time and still have 
decent performance.  This is especially true as traffic starts to climb. 
  That's when you can add in some caching and take a lot of stress off 
the database.  There are a million ways to implement caching, from 
denormalized tables to replicated databases to BerkeleyDB to mod_proxy 
and most web applications have some data that is read-only or close to 
it.  (I know that yours deals with financial data, so in your case it 
may actually have to be all real-time data.)

- Perrin




Re: mod_perl/passing session information (MVC related, maybe...)

2002-06-12 Thread Perrin Harkins

Jeff AA wrote:
 Interestingly MySQL and other DBs are often as fast as simple disk
 access - contrary to popular wisdom, most DB engines actually cache in
 memory, with more data access information and hence effective cache
 memory usage than is available to external cache components. Yes,
 Network transference can be an issue - but hey! be a masochist, buy a
 switch!

It's a simple rule: if you do less work, you will finish faster. 
Reading a file will go to the file system code in the kernel, which uses 
some sort of in-memory cache on any modern OS.  That means that for any 
frequent access data you are reading it from memory using system-level 
calls.  By contrast, MySQL has to deal with network transfers and SQL 
parsing before it reaches that stage.  It's not a huge difference, but 
it is a difference.  I'll have numbers on this stuff soon as part of my 
article on data sharing with mod_perl, so that people can compare and 
see if it's worth the effort for them.

The more important reason to cache is scalability.  Every time you don't 
hit the database, that means more resources are available to handle the 
queries that can't be cached.  On a site with heavy traffic, that's very 
important.

 I parse 'use a cache for db stuff' as 'my XYZ cache component is way
 smarter than all the guys at 'Oracle|Sybase|MySQL' combined', or 'I know
 my data better than the database, cos I'm a kewl Koder'. Actually, I
 really parse 'use a cache for db stuff' as 'I don't really understand
 databases, 3NF and indexing, and can't be bothered learning to use them
 well'.

I've worked with some good DBAs, but there is a limit to what they can 
do.  Ultimately, a database is designed to always give 100% correct 
up-to-date results, but in most web applications people would prefer to 
get slightly out-of-date results if they can get them much faster. 
Databases don't know how to do that.  Why should you go to MySQL every 
time someone hits the front page of Slashdot just to give them the very 
latest count on comments?  Caching that page for 1 minute takes a ton of 
load off the database and doesn't really impact the user experience.

I fully agree that optimizing the database and SQL is the first step, 
but correct use of caching can make a huge difference on high-volume sites.

- Perrin




Re: separating C from V in MVC

2002-06-12 Thread Perrin Harkins

Wow, this is a long one.  As usual, everyone has slightly different
ideas about how to do MVC, so keep a grain of salt handy.

 This basic pattern repeated ad infinitum.  It's grown way out of
 control, is a pain to work with, and just feels wrong, very wrong. :-)

We've all been there.

 1.  Is there one Controller or many?

Usually there are many.

 Should I have one for each main
 area of my site?  /myapp/admin/ goes to an Admin Controller,
 /myapp/reports to another controller, etc...

That's how I would do it.  The idea is to group the things that are
related together, since they tend to change at the same time.

 2.  Does the first part of my code above even remotely resemble a
 Controller?

Sort of.  It does choose a view and it does parse some user input, but a
controller is more than just a dispatcher.  It would include some of the
code that you're currently putting into your doDoctorActivity() sub.
The idea is that the model objects represent just the data in your
application (the nouns) and the controller understands how to translate
user input into a series of method calls on the model objects to carry
out the user's request.

It's hard to give a good example that is short, but let's say you were
building an application to sell concert tickets.  The act of buying the
ticket might involve model objects representing a concert, a user, a
form of payment, etc.  The concert object knows how to reserve a
specific seat (or call a seat object to do that).  The payment object
knows how to verify and charge a credit card.  The user object has a
mailing address.  The controller knows how to turn the user's form data
into a bunch of method calls on these objects that accomplish reserving
the ticket and charging the user.  If you find yourself writing a
BuyTicket module, that's a controller not a model object.

 3.  How do you prevent a Controller from just becoming another big if
 statement, or is this their purpose in life?

If you break up your app into multiple controllers, there will probably
only be a few different actions that each one handles.  That's a pretty
small if statement, or you could use a dispatch table.  Modules like
CGI::Application have already written the dispatch table code for you,
so you just provide the configuration that maps actions to subroutines.

 4.  In the case of a form, what perl structure is used to pass the
data
 into the model?

You don't pass a form directly to a model object.  You parse the form,
then you use the API provided by the model object.  Remember, we want to
be able to use these same model objects from a cron job.

my $hospital = $apr-param('hospital');
$doctor-set_hospital($hospital);

 5.  Do you create an actual class for each form?

Similar to #1, each form might have it's own controller class, or you
might group some related forms (that act on the same data) together in a
single controller.

 6.  Do you need to create objects at all?  Is OO a prerequisite to
MVC?

Modelling your data as objects is sort of an underlying assumption in
MVC.  You could do a clean design without using OO, but it would be a
little odd and the model objects might not be very reusable.

 6.5.  (thought of while proofreading :-)  Is the statement there is
one
 set of controllers for each defined view correct?

No.

 In other words, if
 we someday want to output the reports section of the site as Excel
 spreadsheets in addition to HTML, would we define a new set of
 controllers or how would that work?

You would make your existing controllers understand the piece of user
input or context that means they want Excel format, and have them pass
the model data to a different view in that case.

 7a.  Is it insane to leave my SQL hard-coded in there?

You're going to have SQL somewhere, but if you wrap it up into objects
that represent your data, it's easier to maintain.  It hides all of that
specific database knowledge from the rest of the application and avoids
repitition.

At eToys we had a tremendous amount of data associated with each
product.  It spanned many tables and was not very easy to work with.
However, once I had written an object representing a product, the search
code, shopping cart code, product page code, etc. could all use it.
When we added new properties, I only had to do it one place.

OO modelling is a big subject and lots of good books have been written
on it, so I won't say more about it here.

 7b.  Should I really investigate real object persistence like
discussed
 at the POOP site (I have used Tangram with some success on tiny side
 projects but nothing remotely this size)?

Only if you like what it does for you.  I generally prefer to write the
SQL myself because of the tuning opportunities it affords, but this is
the sort of topic that many people have strong opinions on.  Anyway,
objects that contain hand-coded SQL are just as real as objects that use
a POOP module to generate the SQL for them.

 Begging the question, should
 I really be migrating to 

Re: separating C from V in MVC

2002-06-11 Thread Perrin Harkins

Ward Vuillemot wrote:
 I know we are straying WOT, but I would love to get a better feel for XML, XSLT and 
AxKit.

Barrie Slaymaker has written a couple of articles on perl.com that serve 
as a good intro to AxKit.

- Perrin




Re: separating C from V in MVC

2002-06-11 Thread Perrin Harkins

John Hurst wrote:
 Still, I don't think that replacing this:
 
 Location /search
SetHandler  perl-script
PerlHandler Controller::Search
 /Location
 
 with this:
 
 [% Ctrl.Search() %]
 
 makes Controller::Search any less a controller.

You're right.  It just looks kind of odd to me, invoking a template for 
something that is not a display-related task.  It looks like the way 
people typically do MVC in Mason or Embperl, with a first template that 
doesn't do anything but invoke a module to take over the processing.

 Obviously, the stand-alone dynamic pages are not MVC at all. They exist
 because there are often 'glue' pages that don't warrant the comlexity of MVC
 (those that don't need M and have very simple VC needs).

I agree that there is often a need for some quick and dirty internal-use 
pages (admin or reporting usually) that don't require the extra baggage.

- Perrin




Re: separating C from V in MVC

2002-06-11 Thread Perrin Harkins

Gerald Richter wrote:
 Embperl 2.0 can invoke such a controller (it's called application object
 there) after it has setup it's request parameters (GET/POST data, session
 data, etc.) and before any templates are get a chance to run.

That sounds like a good addition to Embperl.  Can you give a URL for the 
documentation on how to use this?

- Perrin




Re: MVC Topic Joy

2002-06-10 Thread Perrin Harkins

Jon Robison wrote:
  I should never really have to edit
 #3 (the Viewer), because the HTML construction should be done in #2. If
 I find myself editing my viewer to accomodate some function I am adding
 to the overall system, I know I need to re-think what I am doing.

In an MVC system, you would definitely need to edit the controller any 
time you change the input side of the user interface.  You may or may 
not need to change the model and view as well.

Which part handles taking the user input, figuring out which methods to 
call on the model objects, and choosing a view (usually a template) to 
show?  This is all stuff that the controller would do in an MVC system, 
and you don't seem to have one in your description.  If you don't have a 
controller, you will end up wedging that stuff into the model objects 
which makes them a lot less reusable.

Don't get me wrong: a basic script + a template is still better than a 
basic script + a bunch of print statements, but there is value in the 
separation of the controller and the model too.

- Perrin






Re: separating C from V in MVC

2002-06-10 Thread Perrin Harkins

Ray Zimmerman wrote:
 So how is everybody else handling URL mapping?

In httpd.conf:

Location /search
   SetHandler  perl-script
   PerlHandler Controller::Search
/Location

Location /cart
   SetHandler  perl-script
   PerlHandler Controller::ShoppingCart
/Location

Most applications only have a handful of controllers, so this works fine.

You could also look at the way OpenInteract does it, which allows you to 
gather all the related stuff including this configuration into a single 
package that you can install in one shot.

- Perrin




Re: MVC Topic Joy

2002-06-10 Thread Perrin Harkins

Jon Robison wrote:
 In most cases the Handler is set to view, in which case View.pm
 instantiates other modules objects, (and those instantiations use other
 url string data to determine what to construct into the object). View
 then just spits out the default head, body (created with the other
 objects) and footer.

The confusion here is that your View.pm is not a view, but a controller.

  It's the html module's job to fill the return from view_data
 with the correct information.

Then it sounds like the html module is your view.  It's the part that 
accepts data and generates HTML.

- Perrin




Re: separating C from V in MVC

2002-06-10 Thread Perrin Harkins

Valerio_Valdez Paolini wrote:
 On Mon, 10 Jun 2002, John Hurst wrote:
 
 
In the filesystem. Directly requested .tt files are all sent to a
default template handler:
...
 I used html pages with augmented tags parsed by a standard handler:

Those are both interesting and may be the most appropriate solution for 
the problems you're working on, but I wouldn't call either of them MVC. 
  You are going straight to a view (template) and letting it drive all 
the decisions.  In an MVC application, you would go to a controller that 
would do some work and then decide which view to show.

- Perrin




Re: FreeBSD Apache/mod_perl/OpenSRS/expat problem + solution

2002-06-09 Thread Perrin Harkins

 I just ran down a problem that was somewhat hard to find, and I didn't
see any
 mention of anything like it in the archives anywhere.

The expat issue has been discussed quite a bit on this list, and is
documented here:
http://perl.apache.org/guide/troubleshooting.html#Segfaults_when_using_X
ML_Parser

Sorry to hear you had trouble finding it.  That section of the guide is
the first place you should look when you're having segfault problems.

- Perrin




Re: [OT] MVC soup (was: separating C from V in MVC)

2002-06-09 Thread Perrin Harkins

 What I didn't like about this is I then had to adjust the so-called
 controller code that decoded the user input for my request object to
 include these new features.  But really that data was of only interest
to
 the model.  So a change in the model forced a change in the
controller.

No, a change in the user interface forced a change in the controller,
which is fine.  Your user interface now supports parameters of starting
page and page size, so the controller has to know how to handle those
parameters and translate them for the model.  (Incidentally, it's not
such a good idea to make page size a query arg.  Better to put it in
some config file on the server.)

For example, you might have controller code like this:
my $query = $apr-param('query');
my $page  = $apr-param('page');

my $search = Model::Search-new(
query = $query,
page  = $page,
   );

The controller is tightly coupled to parsing and handling user input,
but knows nothing about what that model object will do with it.  It is
basically translating HTTP requests into sets of method calls on model
objects.

 So now I just have been passing in an object which has a param()
method
 (which, lately I've been using a CGI object instead of an
Apache::Request)
 so the model can have full access to all the user input.  It bugs me a
bit
 because it feels like the model now has intimate access to the user
input.

I agree, this is not good.  The controller is supposed to be parsing
that stuff and abstracting it from the model.  The model shouldn't care
if you decide to start encrypting some parameters, or getting them from
the user's session, or using different names for them on different
forms.

 My second, reasonably unrelated question is this: I often need to make
 links back to a page, such as a link for page next.  I like to build
 links in the view, keeping the HTML out of the model if possible.  But
for
 something like a page next link that might contain a bunch of
parameters
 it would seem best to build href in the model that knows about all
those
 parameters.

I don't think it makes a huge difference, but I would probably assemble
these either in the controller or in the view.  The model would just
provide the data.  If they are simple links (i.e. same params always, no
logic) you should be able to use any templating system to build them.
Template Toolkit has a URL plugin for convenience:
http://www.template-toolkit.org/docs/default/Modules/Template/Plugin/URL
.html

- Perrin




Re: Building high load mod_perl/Mason servers

2002-06-09 Thread Perrin Harkins

 We are going to be moving to mod_perl, but I am
 worried about how to keep from getting into the same kind of trap with
 mod_perl as with PHP.

You may want to read my article about building a large site with
mod_perl:
http://perl.apache.org/release/docs/tutorials/apps/scale_etoys/etoys.htm
l.

 So I am thinking whatever I do it should fit within an existing
framework,
 something like Mason. But I am confused about what real advatage Mason
 provides, and how things like source code control would work if we are
 running lots of servers.

Your best bet to avoid spaghetti code with Mason is to use OO perl
modules for all of the real functionality in the application and then
use Mason's components as templates for displaying the results.  Mason
is good at handling the plumbing aspects of web development and
provides an environment for doing HTML templates with in-line perl.  See
this article for more on appropriate use of components and modules:
http://masonhq.com/user/autarch/Comps_vs_modules

There are many frameworks for mod_perl, so if Mason doesn't look like
exactly what you want you can check out some others here:
http://perl.apache.org/#appservers

 Do people use rsync to keep up to date?

If you have a high-volume commercial site, you would be better off with
a slightly more structured process.  You can set up a script to make
releases which will tag the CVS tree and build a release in some package
format like RPM or .tar.gz.  Then you can QA that release and later
install the same release, all with development continuing in CVS for the
next release.  This allows you to easilly go back to a prior release if
a disastrous bug is found in production.  (Well, there are issues like
config files and database changes which complicate things, but that's
the basic idea.)

- Perrin




Re: [OT] MVC soup (was: separating C from V in MVC)

2002-06-07 Thread Perrin Harkins

Bill Moseley wrote:
 My MVC efforts often fall apart in the C an M separation.  My M parts end
 up knowing too much about each other -- typically because of error
 conditions e.g. data that's passed to an M that does not validate.  And I
 don't want to validate too much data in the C as the C ends up doing M's work.

I agree that this is one of the thornier problems.  For simple things 
you can just throw exceptions, as Jesse mentioned.  This is all you need 
to do for system-level problems like failing to connect to the database. 
  The difficult part is when you need to provide feedback to users on 
their incorrect input.

For example, if you have a form for registering as a user which has 
multiple fields, you want to be able to tell them everything that was 
wrong with their input (zip code invalid, phone number invalid, etc.), 
not just the first thing you encountered.

Putting that into a model object is awkward, since coding your 
constructor or setter methods to keep going after they've found the 
first error feels wrong.  You can write a special validate_input() 
method for it which takes all the input and checks it at once returning 
a list of errors.  You could also just punt and push this out to the 
controller.  (Not very pure but simple to implement.)  Either way you 
can use one of the convenient form validation packages on CPAN.

 Anyone have links to examples of MVC Perl code (mostly controller code)
 that does a good job of M and C separation, and good ways to propagate
 errors back to the C?  

You could look at the OpenInteract code.  It includes some good examples.

- Perrin







Re: Separating Aspects (Re: separating C from V in MVC)

2002-06-06 Thread Perrin Harkins

Sam Tregar wrote:
 Now, I don't use HTML::Template::Expr.  I think it's generally not such a
 good idea.  But it's there if you want it...

For posterity, and possible inclusion in the next rev of the templating 
tutorial, how would you recommend people handle this sort of situation 
without using HTML::Template::Expr?

Suppose you have a model object for a concert which includes a date.  On 
one page, the designers want to dipslay the date in a verbose way with 
the month spelled out, but on another they want it abbreviated and fixed 
length so that dates line up nicely.  Would you put that formatting in 
the controller?

What if you had a model object that generates a list of these concerts, 
and on a certain page the designers want to show it in two columns. 
Would you split it into two arrays in the controller?

- Perrin




Re: tutorials (was: Re: rfc Apache::Dynagzip)

2002-06-05 Thread Perrin Harkins

Stas Bekman wrote:
 The ongoing discission of MVC is a good example 
 of a tutorial candidate

Incidentally, I already wrote a fair amount on this subject in the 
eToys-related tutorial:
http://perl.apache.org/release/docs/tutorials/scale_etoys/etoys.html#Code_Structure

There's a diagram, code examples, etc.  I wasn't planning to write a 
spearate MVC one because I've already said most of it there.

- Perrin




Re: DBI Bug

2002-06-04 Thread Perrin Harkins

Udlei Nattis wrote:
 hi, sorry my english ;)
 
 when i add this line in httpd.conf
 
 PerlModule DBI
 
 or
 
 use DBI(); in startup.conf
 
 apache dont start, i receive this error:
 
 /usr/local/apache-2.0/bin/apachectl: line 192: 12547 Segmentation 
 fault  $HTTPD
 /usr/local/apache-2.0/bin/apachectl start: httpd could not be started
 
 i test it in
 Apache 2.0/Perl 5.8.0RC1/Modperl 1.99.02/03
 Apache 2.0/Perl 5.7.3/Modperl 1.99.02/03
 Apache 2.0/Perl 5.6.1/Modperl 1.99.02/03
 Apache 2.0-cvs/All Perls/All Modperls

It definitely works with the Apache 1.x/mod_perl 1.x/perl 5.6.1 combo. 
Maybe someone else can verify that they've run DBI under mod_perl 2?

You might need to use the pre-fork MPM when using DBI, depending on how 
well your database driver works with threads.  You should also make sure 
you compile all of these with the same compiler, to ensure compatibility 
between libraries.

- Perrin




Re: separating C from V in MVC

2002-06-04 Thread Perrin Harkins

Rob Nagler wrote:
 The way I understand how plugins work is that they are arbitrary
 classes.  But how do you share behavior?

I probably wouldn't use a plugin for something that needed to output 
HTML, because that would prevent the designers from editing it.  A macro 
(basically a mini-template) could be broken down into smaller shared 
templates, but there is a practical limit to that approach.

 FILTER does not shared behavior, but is a pipe mechanism.

Yes.  I think it would be a good way to do the FONT trick you mentioned 
though.

 There is no protocol for communicating between these various
 components except well-known global variables.

That's correct.  A template can call macros which are parameterized 
(e.g. a macro for making large text headlines which accepts the text as 
a parameter), but that's not exactly the same thing.  If you find that 
you really need to have stateful widgets that share data beyond whatever 
model data was passed to the view, then templating is probably not an 
appropriate solution.

 For example,
 if a Link is not executable by the current user, it won't render as a
 link (and possibly be completely blank depending on the circumstance
 and configuration).

That's easy to do, but not easy to share between multiple templates with 
different appearances.

 Another concern I have about Template Toolkit (and other template
 languages) is that it has its own syntax and semantics for data and
 control structures distinct from Perl.  Why isn't Perl good enough?

The syntax for accessing complex data structures in perl is non-trivial 
and possibly too confusing for designers.

Here's the perl version:
foreach my $account ( {$model_data-{'user'}-{'accounts'}} ) {

and in TT:
[% FOREACH account = user.accounts %]
or with localized loop variables, like HTML::Template:
[% FOREACH user.accounts %]

 My experience with little languages is that they take on a life of
 their own

That can happen, and I've seen some people do appalling things with 
templating tools, but these people tend to be programmers working by 
themselves with no separate designer.  The place where these tools 
really pay off is when you're working with a separate design group.  My 
experience has been that designers have no trouble grasping the basic 
ideas of templating, and don't feel the need to try and wedge in stuff 
that doesn't belong there.

The thing that worries me about a widget approach is that I would have 
the same problem I had with CGI.pm's HTML widgets way back: the 
designers can't change the HTML easilly.  Getting perl developers out of 
the HTML business is my main reason for using templating.

- Perrin




Re: separating C from V in MVC

2002-06-03 Thread Perrin Harkins

Rob Nagler wrote:
 Perrin Harkins writes:
 
You can actually do that pretty comfortably with Template Toolkit.  You
could use a filter for example, which might look like this:

[% FILTER font('my_first_name_font') %]
... some text, possibly with other template directives in it...
[% END %]
 
 
 One of the reasons Perl is popular is its idioms.  Having to say
 something in three lines is not as idiomatic as one line.  It takes a
 lot of discipline to use it everywhere.  In other words, I don't think
 the above is more comfortable than:
 
 String(['User.first_name'], 'my_first_name_font');

The advantage is that my example can contain other templating code:

[% FILTER font('basic_info_font') %]
   Hello [% User.first_name %]!BR
   [% IF User.accounts %]
  You have these accounts:BR
  [% FOREACH User.accounts %]
[% name %]: [% balance %]BR
  [% END %]
   [% END %]
[% END %]

Unless I'm missing something about your example, the FILTER concept 
seems more powerful.  It is perfectly possible to simply add a plugin to 
TT to make it look like yor example though:

[% String(User.first_name, 'my_first_name_font') %]

 Note also the accessor for User.first_name in Template Toolkit is
 probably nontrivial.

Assuming it's just $User-first_name() and you passed in $User as part 
of your data to the view, there's no additional work.

- Perrin




Re: separating C from V in MVC

2002-06-03 Thread Perrin Harkins

Rob Nagler wrote:
 [Skirting on the edge of YATW. :-]

I certainly don't mean to have a templating war.  I'm just trying to 
figure out what the difference is between these approaches and if 
there's something I've been missing that I should consider adding to 
future applications.

 Here's your expanded example in widgets:
 
 String(Prose('EOF'), 'basic_info_font');
 Hello String(['Model.User', 'first_name']);!br
 If(['Model.AccountList', '-get_result_set_size'],
   Join([
   You have these accounts:br,
   Table('Model.AccountList', [
   'name',
   'balance',
   ]),
   ]),
 );
 EOF

If your String widget can accept other widgets recursively like this, 
then our examples are equivalent.  I thought it was limited to a simple 
value.

 Unless I
 missing something, the template example won't align properly in HTML.
 This is a significant semantic difference between FOREACH and
 Table.

I just didn't put in any fancy HTML in my example.  I could have put in 
table tags right there, or made a macro if that table gets repeated a 
lot.  Looks to me like they work the same.  In TT, I would probably use 
macros or small templates (possibly defined in this same template file 
at the top) for little repeating chunks, and filters or plugins for 
things with more brains, like the String widget that decides whether or 
not it needs to print FONT tags.

- Perrin




Re: separating C from V in MVC

2002-06-02 Thread Perrin Harkins

  It seems problematic to me to require the programmers to do work
when a
  designer wants to change the number of decimals in a page, for
example.

 HTML::Template::Expr may present a solution to this particular desire,
 although it isn't one I've come across.  How often are HTML designers
 fiddling with numeric formats?  Are they really HTML designers if they
can
 deal with, say, a printf-style format string?

Yes, they are, and printf isn't so much harder than JavaScript, style
sheets, and templating tags.  One place where this comes up is date
formatting and internationalization.  Making the model objects
understand locale and act appropriately is not always a good approach,
and supplying a date format in the template - which is all about
appearance anyway - seems appropriate.

This can also be useful when the same date needs to be displayed in
multiple ways, like an abbreviated format on one page and a fixed length
format in an e-mail template.  You could make the controller do this
sort of formatting before passing data off to the view, but I think it's
an awkward fit and increases the coupling between components
unnecessarilly.

Obviously there are lots of ways to solve these problems, but what I
like about doing it in the template is that it puts these concerns in
the hands of the people who control the rest of the look-and-feel issues
in the application, and gets them out of the perl programmers' way.

- Perrin




Re: separating C from V in MVC

2002-06-02 Thread Perrin Harkins

 It is interesting to try and fit our approach into the MVC+template
 pattern

Just to clarify, it's not MVC+template; it's just MVC.  The templates
are one way of implementing views.  You could mix and match this where
appropriate, so that your Excel view is a perl module with a set of
formatting guidelines stored in a sort of style sheet, while your HTML
view is simply a template executed by a templating module.

 I see the Controller as also responsible for deciding what to do with
 the results of rendering the DOM in Excel or HTML formats - Views
 don't decide how their results should be distributed.

This is typically something you would put into the controller, since the
view shouldn't have to worry about details like HTTP headers.

- Perrin




Re: separating C from V in MVC

2002-06-02 Thread Perrin Harkins

 A String widget/template allows you to control the rendering of all
 fonts dynamically.  If the String widget/template sees the incoming
 request is from IE5+, it doesn't render the font if the font is the
 same as the default font.  The Style widget/template renders the
 default font in a style if the browser is IE5+.  This avoids the
 stylesheet bugs in all other browsers and gives 90% of your users who
 are running IE5+ a much lighter weight page.

 It's cumbersome to do wrap all text in string templates, because the
 calling mechanism is verbose.  Most template languages I've looked at
 only support named parameters.

 Widgets can have named parameters, e.g.

 String({
 value = ['User.first_name'],
 string_font = 'my_first_name_font',
 });

 but it is much more convenient to use positional notation:

 String(['User.first_name'], 'my_first_name_font');

You can actually do that pretty comfortably with Template Toolkit.  You
could use a filter for example, which might look like this:

[% FILTER font('my_first_name_font') %]
... some text, possibly with other template directives in it...
[% END %]

The filter is a module which would get to post-process the output of the
contained block.

I believe the taglibs in AxKit could be used in a similar way.

- Perrin




Re: Persistent Net::Telnet Objects

2002-05-31 Thread Perrin Harkins

French, Shawn wrote:
 Recall that I am using: Apache/1.3.20 (Win32) mod_perl/1.25_01-dev
 mod_ssl/2.8.4 OpenSSL/0.9.6a on Windows 2000 with PHP 4.21
 
 Would this be why my scripts are working?

Mystery solved!  Yes, that's why.  You are running mod_perl in single 
process mode because you're on Windows, so only one request is handled 
at a time.  That means that every user will always return to the same 
Apache process, since there is only one of them!

 Does this mean that as long as I
 stay with windows I will be alright?

For certan definitions of alright, yes.  It won't be speedy if you start 
getting many concurrent requests.

- Perrin





Re: Persistant references [was] Persistent Net::Telnet Objects

2002-05-31 Thread Perrin Harkins

First, there is no way to effectively pass compiled code between 
processes at this time.  It isn't likely to happen with Perl 5 because 
attempts at loading compiled bytecode from disk have usually had poor 
performance and other issues.

Second, what you're proposing is probably not a good idea unless this is 
for a small in-house project.

 What I mean is, if a request comes in for a certain form I would like to be
 able to do something like this:
 
 my $form = load_form($r);
 $c{$session_id}-{handler} = $form-{handler}; # -- this being a code
 ref...
 $r-send_http_header;
 print $form;
 
 Then when the user completes the form and resubmits:
 
 my $handler = $c{$session_id}-{handler};
 $r-send_http_header;
 print $handler-($r);

What if the same user has multiple browser windows open and starts on a 
new form before finishing the existing form?  Remember, sessions are 
global to all browser windows.

The right thing to do here is pass the form data the old-hasioned way, 
in URLs or form fields.  Those are distinct for each browser window.

 I would like to be able to dynamically create anonymous
 subroutine handlers based on input and have them be active until the form is
 submitted, at which time they are used to process the form then discarded.

But why go to all that trouble, generating subroutines on the fly?  It 
just doesn't seem necessary for processing form input.

- Perrin




Re: separating C from V in MVC

2002-05-31 Thread Perrin Harkins

Jeff AA wrote:
 do you use any standards for the data being
 returned to the Controller? eg do you use a struct [ie hash/array Perl
 primitive] or do you return an object? eg a table object etc?

HTML::Template requires you to pass a perl data structure.  Template 
Toolkit can handle objects as well (i.e. automatically call their 
accessor methods to fetch properties).  Passing perl structs is faster, 
while passing objects allows for some additional tricks, like 
lazy-loading data in Class::DBI objects.  (Class::DBI is a module for 
modelling database data as objects.)

For more background on templating tools, see my article here:
http://perl.apache.org/features/tmpl-cmp.html

  does the Model returned data contain lots of
 style hints? Or do you leave this completely to the View layer?

Ideally you should have no style information at all in the model.

 How does
 the view layer know for example to render an Error cell as RED in HTML
 but blue in Excel due to Excel palette limitations?

You have different views for different targets.  Make an HTML view and 
an Excel view and have the controller know which one to use.

Optimally, the View avoids *ALL* application logic.  
 
  - so the Model has to say RED rather than ERROR?

Just the opposite: the model provides the list of errors, and the view 
knows how to display them.

 Sounds like Controller only interacts with one Model?

The model might be made up of dozens of different classes, but it's 
still referred to as the model as in the application's data model.

 What controls the overall layout?

The view.

 e.g. what is the equivalent of the
 'Grid Bag' layout manager - is this done in the Controller? and then
 passed to the View with all the data from a set of Models? Or do you 
 make the Controller minimalist and have a meta-Model that assembles
 all the sub-Models into a layout.

I don't know what a Grid Bag is, but the idea is pretty simple:
- Controller looks at input and decides which model objects to call.
- Controller calls some methods on model objects.
- Controller picks a view and passes data from model objects to it.

I wrote about this in my article on the eToys system:
http://www.perl.com/pub/a/2001/10/17/etoys.html

- Perrin




Re: separating C from V in MVC

2002-05-31 Thread Perrin Harkins

Hi Jesse,

 It's the addition tricks which bug me out.  With those two words you
 establish the mother of all slippery slopes to architecture oblivion.  When
 you have objects passing freely between your Controller and View (which
 are quoted here, 'cuz I don't think they are separate in this case), how do
 you decide where to put a particular bit of code?  The answer is, it is
 completely arbitrary.

First of all, I don't do it that way.  I pass simple Perl data 
structures to Template Toolkit, because I know what data I want to send 
and it's faster that way.

However, I don't really understand your objection.  The view doesn't get 
to do anything but call accessor methods on the object.  They look just 
like simple structures:

NAME: [% person.name %]

The template coder doesn't know that person is an object and TT called 
a method to get that instead of just doing a hash lookup.

The reason people usually do this is so they can do lazy-loading.  With 
something like Class::DBI you can set it so that if no one ever uses 
person.name in a template it will never be loaded from the database. 
It's a performance optimization.

People who like that approach have objected to my approach of passing 
data because it requires the controller to know exactly what data the 
template will need, or else pass data that may not be needed and 
possible waste effort.  Personally, I don't mind having the controller 
know what data is needed, as long as it doesn't make any decisions about 
how the data is shown.

 In the architecture you describe it is inevitable that given enough time and
 different programmers your Controller and View will coalesce into a
 undifferentiated mash of code and HTML, separated only by the fact that they
 are in two different files.

I don't see where you're getting this from.  The objects return data, 
not HTML, and they have no side effects.  They are read-only.  The view 
(template) does all of the formatting.

 IMHO, any system built on Template Toolkit (unless it is small and always
 managed by the same programmer) will ultimately devolve in just the same way
 as a Server Page system.

Well, you're not right about that.  We built a very large system at 
eToys using TT and it never had any of these problems you're describing. 
   The separation was clear, and the templates did nothing but display data.

 HTML::Template isn't just faster than just about
 everything else out there -- it also is pretty much the only templating
 system which has an actual clear vision when it comes to how it fits into
 the larger architecture.

I don't agree with that either.  Template Toolkit and AxKit (or any 
other XSLT-based system) can both enforce a clear separation of 
responsibilities.  Template Toolkit allows people to do it other ways if 
they want to, through the use of plugins or by passing objects that do 
more than just return data, but the documentation and most of the 
mailing list discussion centers around the same approach as HTML::Template.

The speed differences aren't really significant at this point.  All of 
these tools are blazing fast.  They all have C code under the hood now 
(with the new HTML::Template compiler).  The bottleneck on performance 
of web applications is still what it always was: data access.

- Perrin




Re: [Mason] Re: separating C from V in MVC

2002-05-31 Thread Perrin Harkins

Dave Rolsky wrote:
 Alzabo could handle a _lot_ of this for you.  Class::DBI could handle some
 of it (though less).

SPOPS is also a good choice for this.  All of them are on CPAN, just 
waiting for you.

- Perrin




Re: separating C from V in MVC

2002-05-31 Thread Perrin Harkins

Jeff AA wrote:
 For example to render a date in Excel some jiggery pokey is required,
 and I would also expect a HTML V to print pretty dates rather than 
 20020531172534 (or something other than the raw stringification)

Yes.  That's why you need to use a good templating system.  There is a 
plugin for date formatting in Template Toolkit and HTML::Template can do 
it by using the HTML::Template::Expr module.  Maybe some AxKit expert 
could explain how to handle it there.

 We also deal with lots of numerics - some are quantities, and others 
 are values or interest rates - they need zero, 2 or 4dps when being
 presented.

Same deal: TT has a formatting plugin, and HTML::Template::Expr gives 
you access to sprintf or an arbitrary formatting function of your own.

 So for
 example if your savings balance has gone negative, the value should
 be rendered as an error balance rather than a normal balance. In
 HTML you might choose to display the cell with a RED background,
 but this does not work in Excel, where a RED background prints as
 black, so you can't just tell the view RED - you need to tell it
 the reason and let Excel choose one of its limited bg colours.

A simple approach for this would be to have a data model that includes a 
boolean flag for whether or not this balance is overdrawn.  For example:

my $balance = {
value = -7,
overdrawn = 1
   };

Note that the model object is making the decision about whether the 
balance is overdrawn and no logic about that is going into the template.

Then in your template you say something like this:
[% IF balance.overdrawn %]
   bgcolor=red
[% END %]

Or whatever makes sense for your target output.

 Ok - so results from a collection of models are assembled and 
 passed to the view.

One model, made up of many data objects.

  - not sure if I like this. I thought the whole point of the View
 was to contain all the logic about things like HTML tags or Excel binary
 representation etc, and as little as possible about other things.

That's right.

 Exactly where in the MVC world, would I decide that column 3 which
 contains a description should expand to fill 70% of the available 
 space and that column 5 which contains a possibly long name should 
 use the remaining available space, whilst column 1 which contains
 a name should not be wrapped?

In the view.  I'm not sure where your confusion lies here.

 I guess I have talked myself round to thinking that the Controller
 is actually the layout manager, in that it marshals results from
 a set of models, decides how this collection should interact, and
 then asks an appropriate View to render the result in a specific
 interface flavour.

That's exactly what I'm saying, except that I don't see what your 
layout manager is for.  You should just pass some data to a template 
(or maybe to something fancier for certain types of output like Excel) 
and then the template makes all the decisions about how to show that data.

 Have I talked myself out of HTML:Template route? Not sure, I guess
 it depends on whether HTML::Template can be smartened up to 
 understand that I want Dates rendered in a pretty format, quantities
 should be commified, cash values must have commas and 2dps, interest
 rates should have 4dps and cells with an error attribute should have
 a red background.

No problem, as I explained above.

- Perrin




Re: separating C from V in MVC

2002-05-31 Thread Perrin Harkins

Rob Nagler wrote:
 Layout managers accept a declaration ('this cell is northwest', 'this
 other one expands across the bottom', etc.).  They interpret the decl
 at run-time.  It's like HTML, but more declarative.  Some attributes
 of our Grid manager are:
 
   cell_nowrap - don't wrap the text in the cell
   cell_align - gens valign and align from a single compass direction
   cell_expand - this cell eats up the rest of the columns in the row
   row_control - a conditional value to control whether row is displayed
   cell_width - contains the HTML width= value (may be dynamic)

Can't all of that be expressed in an HTML template?  It seems like the 
template should know enough about what kind of data it's displaying to 
know how to arrange the tables.  After all, it's not a template for a 
generic table; it's a template for a table that displays specific data 
with a structure that is pre-determined.

Usually when I see people doing this kind of thing it's because they 
haven't expressed all the necessary information in their model.  For 
example, if you have a rule that says people's names don't get wrapped, 
then you need to know which pieces of data are names.  If that isn't 
obvious from your data structure (i.e. person.name is always a name) 
then you add some flag to your data structure like is_name, so that the 
model can tell the view that this is a name.  Then the view gets to 
decide what special treatment to give that data.

Maybe there's a certain class of problems where the sort of layout hints 
you're talking about are needed and I've just never had to deal with it.

- Perrin




Re: separating C from V in MVC

2002-05-31 Thread Perrin Harkins

Rob Nagler wrote:
 Let's say, though, that you want the same template to render
 in a WAP, Opera, Konqueror, IE, NS, etc.  The implementation of Grid
 handles this for you.  For example, our code automatically renders
 style sheets for IE5+, but no other browsers.  (This isn't in Grid,
 but you get what I mean, I hope.)

The same template?  How does the layout manager help with that?  Does it 
modify the template?  It would make more sense to me if this were a sort 
of abstraction to factor out common layout ideas from multiple templates.

 However, sometimes you have dense tables where you allow wrapping and
 other sparse tables where you don't.  We have a really wide table for
 admins which allows them to see all EC info at a glance.  It has to
 wrap all cells or it wouldn't fit on some screens.  When the customer
 sees the payment reason, on their subscription page, it doesn't wrap.
 Two views of the same data.

That doesn't require a layout manager though.  Simple templating is fine 
for that, i.e. two different templates (views).

- Perrin




Re: MVC advice..?

2002-05-29 Thread Perrin Harkins

Rafiq Ismail (ADMIN) wrote:
 Now my problem is that I have to assign which
 Subclass I want to instantiate, based on the script and params.

So, you're asking how to map URLs to perl modules?  Is there some reason 
you aren't simply using httpd.conf or Apache::Dispatch?  In my last MVC 
design, we had all of our controllers inherit from one base controller 
that held all of the common code.  Then we could just map from URLs to 
the specific controllers that handled them:

Location /mycontroller
   SetHandler  perl-script
   PerlHandler My::Controller
/Location

 I my last
 effort I went for a Shared datastructure holding (script, control module
 pairs) which then allowed one to be dynamically eval 'use..''ed in the
 main content handler.  I found that clunky.

There's no good reason to do an eval 'use'.  Use require instead, and 
import if you need to (but most people don't).

 I'm building from scratch
 again and am thinking of just firing up a template and allowing the
 control to be loaded INTO the view as a template toolkit plugin.  What I
 hate about this is that I'm surrendering my View layer.

I agree, that's a bad idea and certainly not MVC.

- Perrin




Re: separating C from V in MVC

2002-05-29 Thread Perrin Harkins

Ray Zimmerman wrote:
 If I understand correctly, the Mason component that generates the page 
 the user sees would be considered the View. But where is the Controller?

I wrote a little about this in my templating guide, and there has been 
discussion on the Mason list.  A common approach is to use Mason's 
autohandlers as controllers, but you could really use any component. 
Just have it do some work in perl, gather some data, and then pass it 
off to a view component that generates the HTML.

 This is code I
 would normally have put in the %init section of the display component 
 (with a possible redirect to another component based on application 
 logic). This sounds like C and V are not separated as they should be.

That's a standard way to do it in Mason, but not an MVC way.  To make it 
more MVC, you need to have separate components for C and V, with V just 
receiving data and displaying it in HTML.

- Perrin





Re: MVC advice..?

2002-05-29 Thread Perrin Harkins

Dave Rolsky wrote:
 On Wed, 29 May 2002, Perrin Harkins wrote:
 
 
There's no good reason to do an eval 'use'.  Use require instead, and
import if you need to (but most people don't).
 
 
 Actually, there is.  This code:
 
   my $module = 'Foo::Bar';
   require $module;
 
 is not the same as this:
 
   require Foo::Bar;
 
 If require is given a string, it looks for a filename _matching_ that
 string.  If it's given a bareword, it converts '::' to filesystem path
 separators first.

Then do an eval 'require Foo::Bar', but eval 'use Foo::Bar' doesn't make 
sense.

- Perrin




Re: MVC advice..?

2002-05-29 Thread Perrin Harkins

Rafiq Ismail (ADMIN) wrote:
 I'm not so keen on loading all the inheriting classes into memory
 beforehand

You really should do that, because it will save overall memory by 
increasing the amount of memory that's shared.  All modules should be 
loaded during startup in the parent process.

 It's a
 fairly large site and my main concern was to do with how I should store
 the correspondence from uri to object.

The httpd.conf format seems about as simple as you can get to me.  It's 
pretty unusual for a site to have dozens of controllers, and it usually 
indicates a design problem.  Apache::Dispatch is fine too.

 How does StatINC behave with 'required' packages?

Require and use are very similar and both add the loaded module to %INC. 
  Read 'perldoc -f use' for the exact differences.

- Perrin




Re: Persistent Net::Telnet Objects

2002-05-29 Thread Perrin Harkins

French, Shawn wrote:
 Although this is working right now, I don't know enough [ anything? :) ]
 about Apache or mod_perl to be sure that this will work in the future.

I can't see how it could be working now, unless it is actually creating 
a new Telnet object on every request.  Your %sessionHash is not shared 
between processes and you have no control over which process will handle 
any request.  You're probably opening new telnet connections from each 
apache process.

 What
 I am really concerned about is that the telnetObj will only be accessible
 from scripts run by the same child process as that which created and saved
 it.

That won't work, since you can't control which process will handle 
requests from the client.

 Is there a better way to do this?

You could write a web server in Perl, which would run a separate 
persistent process for each client on a different port.  Randal wrote a 
column about that: http://www.stonehenge.com/merlyn/WebTechniques/col23.html

You could also use this technique to make a sort of telnet server, and 
hide that server behind Apache/mod_perl, i.e. clients talk to mod_perl 
which talks to the telnet server.

Of course the simplest approach would be to just let each Apache process 
open telnet sessions as needed.

- Perrin







Re: Apache::DBI connection cache

2002-05-22 Thread Perrin Harkins

Ask Bjoern Hansen wrote:
 Apache::DBI is turning the argument hashref into the cache key 
 with the following code,
 
   my ($key, $val);
   while (($key,$val) = each %{$args[3]}) {
$Idx .= $;$key=$val;
   }
 
 can anyone think of a good reason not to change that to something 
 like
 
   map { $Idx .= $;$_=$args[3]-{$_} } sort keys %{$args[3]};

Good find.  That's a bug.  Fix it.

- Perrin





Re: Apache::GTopLimit

2002-05-21 Thread Perrin Harkins

Stas Bekman wrote:
 Hmm, when a new process starts it shares *everything* with the parent. 
 Why do you say that it's not?

It doesn't share everything with the parent.  As soon as it forks there 
is unshared memory, and after the first request it handles there is 
usually more.

Over time, the average amount of shared memory among child processes 
seems to gradually decrease.  Restarting fixes this.

- Perrin




Re: Apache::GTopLimit

2002-05-21 Thread Perrin Harkins

Stas Bekman wrote:
 What you are saying is that when the server is started afresh, the newly 
 started child processes share more memory with the parent, than newly 
 started child processes some time later. Am I correct?

Yes, exactly.




Re: Apache::GTopLimit

2002-05-21 Thread Perrin Harkins

Stas Bekman wrote:
 Perrin Harkins wrote:
 
 Stas Bekman wrote:

 What you are saying is that when the server is started afresh, the 
 newly started child processes share more memory with the parent, than 
 newly started child processes some time later. Am I correct?


 Yes, exactly.
 
 
 Any ideas why?

Not really.  I thought maybe it was because of something changing in the 
parent process, but that doesn't seem possible.

There was a long thread a little while back about turning swap off and 
on again to solve this.  I've never tried that.  I think restarting 
every 24 hours is a good idea anyway, because I've seen strange things 
happen now and then when a server is up for a long time.

- Perrin




Re: GTop

2002-05-21 Thread Perrin Harkins

If you're not able to resolve your difficulties with GTop, try
Apache::SizeLimit instead.  It fully supports FreeBSD.  You just need to
install the BSD::Resource module, which is useful to have anyway.

- Perrin




Re: Image::Size, TT, and mod_perl Question

2002-05-21 Thread Perrin Harkins

  my %vars = {TOO_WIDE = 1};

That isn't doing what you think it's doing.  Try this:

my $vars = { 'TOO_WIDE' = 1 };



Re: Memory Leaks

2002-05-20 Thread Perrin Harkins

Gregory Matthews wrote:
 I too thought of setting a cron job to restart the server once per day 
 in order to keep the memory fresh.
 
 In a production environment, are there any downsides to doing this, 
 i.e., server inaccessibility, etc..?

There have been some discussion on the list about this in the past.  The 
ideal situation is to have a cluster that you can do a rolling restart 
on without making the service totally unavailable.

- Perrin




Re: Memory Leaks

2002-05-20 Thread Perrin Harkins

Per Einar Ellefsen wrote:
 And if something goes wrong? You'd be having a server offline with noone 
 knowing about it.

You can easilly set up mon (http://www.kernel.org/software/mon/) to page 
you if the server doesn't come back up within a certain amount of time.

- Perrin




Re: Memory Leaks

2002-05-20 Thread Perrin Harkins

Jason wrote:
 If you don't want to restart the server then don't do this instead, it should 
help prevent small leaks from being a problem.
 http://httpd.apache.org/docs-2.0/mod/mpm_common.html#maxrequestsperchild

Apache::SizeLimit or Apache::GTopLimit is a better way to do it, since 
it results in fewer unnecessary restarts.  However, it's still a good 
idea to restart periodically, because some of the shared memory seems to 
become unshared over time no matter what you do, and restarting fixes that.

- Perrin




Re: Monitoring the processes

2002-05-20 Thread Perrin Harkins

Gregory Matthews wrote:
 For example, is there a command line tool to use that will allow me to 
 see the process growth upon request reload?  I know that I should run 
 the server with httpd -X, but I don't know how to actually see the 
 memory being used/increased/decreased when the prog is being executed. 
 As I understand it, this is a good indication that there might be a 
 problem.

You can steal some code from Apache::SizeLimit or Apache::GTopLimit to 
print the current size in the error log.  Otherwise, just use top.  Keep 
in mind that sometimes a leaky piece of code will have to be run several 
times before you see the leak, because of the way that Perl allocates 
memory in chunks.

- Perrin




Re: Apache::GTopLimit

2002-05-20 Thread Perrin Harkins

 Does using the Apache::GTopLimit module have the same net effect as
 restarting the server itself by simply killing off the actual
processes
 which are growing beyond the set threshold, and thereby causing new
 processes to be born?

It does kill off processes that are getting too big, and you definitely
should use either GtopLimit or SizeLimit to get the most out of your
server.  However, it's not quite the same thing as a restart.  Over
time, some of the shared memory from the parent process appears to
become unshared, and new processes that are spawned start out with less
shared memory because of this.  Restarting now and then takes care of
this problem.

- Perrin




Re: Apache::GTopLimit

2002-05-20 Thread Perrin Harkins

 So to modify my previous question, other than the loss of some shared
 memory over time,  GTopLimit will have the same effect as restarting
the
 server?

Yes.  That shared memory is important though.

 On a side note, how are you tracking/discovering the this minimal loss
over
 time?

Apache::SizeLimit prints statistics to the error log when it kills a
process.  Also, you can just look at top.

- Perrin




Re: Memory Leaks

2002-05-19 Thread Perrin Harkins

 I have a couple of questions regarding leaking memory in mod_perl:

 1.  What are the main culprits, in order of severity, of memory leaks,
i.e.:

 a.  global variables (NOT lexically scoped via my)
 b.  ...
 c.  ...

 2.  When writing code from scratch (a new application), what is the
best
 way to avoid creating leaks to begin with, i.e., use strict;, PerlWarn
On,
 etc.. ?

There are actually not very many ways you can leak memory in Perl (and
thus mod_perl).  Most people confuse memory growth with memory leakage.
If you want to know how to avoid memory growth, look at the performance
tuning stuff in the Guide, like passing references, avoiding slurping of
large files, controlling the buffering of DBI result sets, etc.

Leaks are caused by circular references, the string form of eval (at
least it used to leak a little), nested closures (sometimes created
accidentally with the Error module), and one or two obscure syntax
problems.  I think one of them involved code like my $x = 7 if $y;.
Matt Sergeant got bitten by this in the early stages of AxKit
development, and the details are in the mailing list archive.

Global variables by themselves are not a source of leaks or growth.  If
you slurp a large file into a global, your process will grow, but the
same is true for a lexical.

- Perrin




Re: Memory Leaks

2002-05-19 Thread Perrin Harkins

 So am I being overly paranoid concerning the leak potential of
mod_perl
 programming?

No, memory management is very important with mod_perl.

 If I start with strict code to begin with and try my best to stay
away
 from the problems you mentioned, then any potential memory leak/drain
 issues will be avoided?

Using strict is an absolute must for many reasons.  It won't prevent you
from using up tons of memory though.  You have to become tuned in to the
things that use up memory so that you can avoid them.  Start with the
Guide.

- Perrin




Re: sending CGI ouput through a handler

2002-05-19 Thread Perrin Harkins

 My::Handler takes the requested file and adds some markup to it with
the
 Template Toolkit if the MIMEtype of the file is text/html.  I want to
be
 able to use the same handler to also add markup to the output of
executed
 CGI.  What is the best way to do this?

You can't feed the output of mod_cgi to mod_perl, at least not in Apache
1.x.  The best thing to do (at least for performance) would be to
rewrite the CGI so that you call it as a module from your handler.
Another approach would be to use Apache::Filter to grab the output from
PerlRun or Regsistry.  You could also sublass PerlRun or Registry and
add your handler code to it.

- Perrin




<    1   2   3   4   5   6   7   8   9   10   >