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

Reply via email to