in reply to Re^2: source filtering and mod_perl2
in thread source filtering and mod_perl2

So, how does your script fail? We are not mind readers, and if you don't tell us, it makes it much harder for us to find out whether we are seeing the same issues that you see.

As a side-note, I think it's unwise to use @ as a delimiter for your filter when @ is quite prone to also occur within the output you are constructing. I would rather use here-documents or some escapement scheme.

Replies are listed 'Best First'.
Re^4: source filtering and mod_perl2
by Logicus (Initiate) on Aug 28, 2011 at 22:11 UTC
    Bareword found where operator expected at /var/www/ line 20, n +ear "]stash" (Missing operator before stash?) [Sun Aug 28 23:07:59 2011] [error] syntax error at /var/www/ l +ine 18, near "html>"\n syntax error at /var/www/ line 20, near "/]</title"\n BEGIN not safe after errors--compilation aborted at /var/www/ +line 24.\n

    It seems that when I run it under mod_perl the filtering doesn't happen and it tries to run it without it and thus fails. The exact same file is fine as vanilla CGI but when you add the overhead of connecting the database everytime the performance is still pretty poor... 0.04 ~ average per request.

      Looking at (the source of) Apache::PerlRun, it basically is:

      my %orig_inc = %INC; my $eval = join '', 'package ', $package, ';use Apache qw(exit);', $line, $$code, "\n"; $rc = $pr->compile(\$eval);

      ... and as $code gets loaded by a plain file read, source filters never get the chance to actually modify the code.

      You could maybe use a two-level scheme of having the first code be a wrapper that loads your to-be-filtered code. Personally, I would look instead at Plack/PSGI, which eliminates much of the middle man and should work with source filters. When it comes to deploying, source filters also should still work, and if not, you can always use Apache as a transparent proxy in front of your plack application.

        Just wrote the following; need to work on it more but it's starting to look good and it's hella' fast. I need to get this plack thing figured out so I can stick them together.
        listing of /var/www/ -------------------- #!/usr/bin/perl use Modern::Perl; use aXML2; our $stash = { site_title => "bob's bit'z emporium" }; our $bob = "scalars"; my $ctr; sub test { $ctr++; "run $ctr"; } $_ = qq` <aXML> <head> <title>[stash]->{'site_title'}[/]</title> </head> <body> <h1>[stash]->{'site_title'}[/]</h1> (test)(/)<br/> (test)(/) () bracket commands don't cache and <br/> (test)(/) run every time they are called <br/> <test></><br/> <test></> <> bracket commands do cache and retain<br/> <test></> their value once computed <br/> [aXML_cache]->{'test'}[/] <br><br> [] bracket commands interpolate values<br/> in [bob][/] and hashrefs<br/> <br><p> believe it or not just those tags are all you need template<br/> wise. Logic should be in modules, not the templates!</p> <p>aXML2 is far less expressive than aXML, but far faster.<br/> The aXML code gets filtered into raw perl commands then <br/> compiled and executed by Eval::Compile resulting in<br/> performance not far short of executing plain perl.</p> <p>One notable loss for the sake of performance is the<br/> ability to build complex declarations from groups of<br/> simple ones. I am hoping to bring some of that flexibility<br/> back as I work on the filter more. Since the code is only<br/> filtered once on the child process startup, performance<br/> should remain high.</p> (aXML::Bench::EndReport)(/) </body> </aXML> `;aXML2; Listing of /etc/perl/ ------------------- use Modern::Perl; use Eval::Compile qw ( ceval ); use aXML::Bench; our $cache; sub aXML2 { local $_ = $_[0] ||= $_; &aXML::Bench::Start(); s/@/\@/gs; s@<aXML>@print qq`Content-type: text\/html\n\n<html>@gs; s@<\/aXML>@<\/html>`;@gs; s@\(([^\(]+?)\)([^\(]*?)\(\/\)@`; print &$1($2); print qq`@gs; s@\[([^\[]+?)\]([^\[]*?)\[\/\]@\$$1$2@gs; s@<perl>@\@;@s; s@</perl>@print qq\@@s; s@<([^<]+?)>([^<]*?)</>@`; \$aXML_cache->{'$1'} = &$1('$2') unless \$aXML_cache->{'$1'}; print \$aXML_cache->{'$1'}; print qq`@gs; ceval $_; } 1; Listing of /etc/perl/aXML/ ------------------------ package aXML::Bench; use Modern::Perl; use Time::HiRes qw ( gettimeofday tv_interval ); my ($start,$end,$elapsed,$fps); sub MileStone { End(); my $report=Report(); Start(); return $report;} sub EndReport { End(); return Report(); } sub Start { $start = [ gettimeofday ]; return ""; } sub End { $end = [ gettimeofday ]; return ""; } sub Report { $end = [ gettimeofday ]; $elapsed = tv_interval($start,$end); $fps = int(1 / $elapsed); return "$elapsed = $fps p/s"; } 1;