Thanks Warren for the write up! Sounds pretty exciting going full on into a new framework and having that stick even better.

I built Apache::ASP back in the day when both PHP and Java were toys (even Linux was half baked), and glue of the web and unix systems was often perl, my first love of a language. Its all gotten a bit more evolved since then to say the least. :)

& thanks for hanging out these past years on the list!

Cheers,

Josh


On 5/21/14 4:42 PM, Warren Young wrote:
On 5/20/2014 13:06, Josh Chamas wrote:

So where does this put you in the consideration of platform migration
etc? Plack, Mason, TT, etc.

Shortly after I started this thread, I decided to just try one of the
alternatives, for education value if nothing else.

I narrowed my options to Dancer and Mason+Poet, as those are the only two
popular, full-featured, actively-developed Perl web frameworks that still run
under Perl 5.8, which we're going to have to support for years yet.  Mojolicious
and Catalyst are the other main options, and they both require 5.10.

Mason is functionally quite similar to Apache::ASP, whereas I'd say less than
50% of Dancer directly maps to the ASP way of doing things. Nevertheless, I
decided to start with Dancer purely because it has a more active mailing list.
I told myself that I would fall back to Mason if the Dancer experiment fizzled.
As it turned out, Dancer delivered in spades, so I never did spend any time with
Mason+Poet.

About the only things in Dancer that map 1:1 to Apache::ASP -- or near enough
that simple regexes can fix up most of the differences -- are the Request,
Response and Session objects.

Dancer differs from Apache::ASP in pretty much every other way:

- There is no direct equivalent of Apache::ASP's Application and Server
objects.  The features are all present in Dancer, but not collected together in
the same way.  For example, $Server->Config('foo') is config->{foo} in Dancer.

(As a rule, Dancer function and object names are shorter than in Apache::ASP.
For another example, $Request->QueryString('foo') is param 'foo' in Dancer.)

- Dancer's API is a DSL rather than idiomatic Perl as in Apache::ASP. This
bothers to about the same extent that <script> blocks in an HTML file bother
me.  Bouncing between languages adds a context switch while reading code; it's
worst when you have blocks of code that fill a screen, so that you have to
remember context of language A across a screenful of language B.

Apache::ASP can't throw stones, though, due to the mixing of Perl and HTML in
*.asp files.  It's easier to wrap the Dancer DSL in a Perlish API than it is to
avoid Perl code in *.asp files.

- Apache::ASP's URL handing is file-based.  That is, the mere existence of
$webroot/foo.asp means http://server/foo.asp is a legal URL.  Dancer, like many
newer frameworks, has a route-based URL system, meaning that you define your
dynamic URL hierarchy in code, rather than in the filesystem.  (Static resource
files are still mapped directly to URLs in Dancer, of course.)

The files your route handlers use to fulfill each request is entirely up to the
you.  Some kind of straightforward 1:1 mapping (e.g. /foo/bar uses
views/foo/bar.tt) is sensible, but not by any means required.

- Dancer encourages you to separate your GET and POST handlers into separate
routes, whereas with Apache::ASP, the path of least resistance is to put them
both in the same file, for much the same reason that CGI scripts have GET and
POST handling in the same file.  You end up with stuff like:

     if ($Request->{Method} eq 'POST') {
         # Examine $Request->Form to figure out what kind of POST it is,
         # extract data from the form data, process it, etc.
     }
     else {
         # Do something entirely different for GET
     }

     # Render page, either a fresh one for the GET case, or a response to
     # a form submission in the POST case.

Separating your POST and GET routes reduces at least one indent level, and keeps
mostly-unrelated code separate.  It also works better with Ajax-based code,
since GET usually returns HTML, whereas POST will more likely return JSON.

- Dancer has built-in automatic data serializers for several common formats:
JSON, XML, YAML, Data::Dumper...

This is great for Ajax code since:

     return {
         foo => 'some value',
         bar => ( 'a', 'set', 'of', 'other', 'values' ),
     }

...serializes naturally to a JSON object.  My Apache::ASP pages that returned
JSON had to manually set Content-Type and manually call JSON::encode_json() to
serialize my Perl objects for return from Ajax handlers.

- Dancer offers many different templating systems, whereas Apache::ASP offers
just the one.  Only one of the templating systems with a Dancer adapter on CPAN
-- Mason -- works anything like the ASP templating language, in that it allows
you to freely intermix HTML and Perl.  I initially tried using Dancer + Mason to
minimize the amount of work needed to translate my ASP code, but after running
into some difficulties I switched to Text::Xslate, and got hooked.

Systems like Xslate force you to collect all of the Perl code to build a page
into one location, and write the template as a separate file.  This makes both
the Perl and template code clearer, since you're not visually jumping back and
forth between languages, as touched on above.

Template systems like this get you a lot of the benefits of the MVC paradigm
without trying to hammer your square app into the round MVC hole.

(That's another reason I rejected Catalyst, by the way.  My app really only has
Views.  The closest thing to a Controller is the back-end server, written in
C++.  There's a Model, but the Perl code doesn't talk directly to it through a
framework-mandated DBI/ORM scheme; in my app, the Model is hidden behind an
application server.  MVC web frameworks assume M, V, and C are all in Perl, or
at most one hop away such as a MySQL DB via DBI.  Both Apache::ASP and Dancer
(and Mason for that matter) are policy-free frameworks, not prescribing specific
ways of building your app.)

I tell you all this because what happened is that after climbing the initial
learning cliff, I didn't run into any serious trouble.  Dancer just kept
delivering.  Every time I tried porting over another tricky part of the web app,
it was just as easy to get it working with Dancer as with Apache::ASP, and often
the result was easier to understand.

I don't say this to disparage Apache::ASP.  It's a fine framework, and did the
job for us for a dozen years.  For that, Josh, I thank you.

The thing about Dancer is that it's simply based on a more modern, more mature
design.  Separation of concerns, multi-level logging, web stack independence
thru PSGI/Plack, etc.

Because I kept failing to run into a wall with Dancer, and because the future of
mod_perl looks so uncertain -- certainly on RHEL out of the box -- I just kept
translating more and more pieces of my app.  It's now running flawlessly.  The
code is far clearer, partly because of the mature Dancer design, but also
because the forced refactoring made me look at code I hadn't touched in years
and bring it up to date.

Our new version is also faster, in large part because for our app, a single
long-lived application process has no downsides worth mentioning.  We don't need
parallel dynamic code generation, since our app rarely has even 100 simultaneous
users per site, and those are mostly idle all the time.  Thus, the only thing
that really needs to be parallelized is the static content, which is readily
done with Apache + mod_proxy or nginx.

Because of that, we can use fast in-memory sessions, we don't need a bunch of
heavy Apache children hanging around and getting re-created every 500 conns, our
back end app server connections can stay up as long as the session stays up, 
etc.

I therefore say with fondness and a tinge of regret, "So long, and thanks for
all the fish."

I will remain subscribed, since this is a low-volume list.  I may be able to
continue helping others with Apache::ASP.  For myself, though, I'm a convert.
All new code will be in Dancer.

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscr...@perl.apache.org
For additional commands, e-mail: asp-h...@perl.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscr...@perl.apache.org
For additional commands, e-mail: asp-h...@perl.apache.org

Reply via email to