Hi friends,

Is this a rant? A random thought? A pontification? Well, let's say it's
just a personal story (and a concern) I want to share with my fellow
Cocooners...

Someone said continuations can be grasped in five minutes, but it
may take a lifetime to master them :-)

When first introduced to web programming with continuations I was
profoundly impressed to see how continuations "reinvert IoC" and turn
event-oriented programming into good ole' sequential programming.

I was even more impressed to see how -with continuations- the infamous
back button could become in fact a new, all-powerful tool for what-if
scenarios and exploratory browsing.

Boy, is this a triumph of spirit over matter! :-)

After such intellectual orgasm it followed naturally that -from now on-
all my EJB-based webapp development *had to* be developed using Cocoon's
flowscript.

Unsurprisingly, I was rapidly hit by real-life's nasty habit of
impairing golden hammers:

After executing a database-modifying EJB method from the flow, I saw how
invoking the same continuation twice resulted in inconsistent database
state! Obviously, database modifications reflect all updates made
throughout the session, regardless of continuations...

In general, any store will reflect changes made in time. Continuations
only preserve _program_ state. Store state has to be accounted for
separatedly. Thus, continuations wouldn't spare me from having to keep
some sort of explicit dialog control after all...

Since I was playing with a utility "screen" Javascript object (not
unlike Chris' [JX]Form wrapper) I was able to easily add a low-level
sequence number check to ensure "obsolete" continuations were detected
and rejected. Easy hack: it didn't propagate to my application-level
flow code.

All of my dialog pages had a "Cancel" button users could click on at any
time to abort the current transaction. Checking to see if it was pressed
became sort of an "aspect" for every submitted page.

Because pages can be sent ("executed") at any function call nesting
level I decided to implement cancellation processing as a Javascript
exception that propagates all the way up to the top-level sitemap
function dispatcher. Later on, I realized it would be more elegant (and
continuation-aware) to create a globally accessible continuation inside
the dispatcher and use it as an "escape procedure." Upon invoking such
continuation, all other outstanding continuations should be invalidated.

I also "faked" a Javascript component manager which -in absence of the
upcoming Cocoon blocks- would provide me with subsitemap-specific
components for use in my flow.

By combining form objects, local components and [remote] EJB's, I could
keep my flow logic *strictly* flow-related:

        ...
        dataModel.dateFormatter = components.dateFormatter;
        ...
        welcomeScreen.execute(dataModel);
        dataModel.requestData =
                requestDataScreen.execute(dataModel);
        dataModel.requestAnalysis =
            requestManagerEJB.analyzeRequest(dataModel.requestData);
        if (requestAnalysys.evaluation == APPROVED) {
                confirmationScreen.execute(dataModel);
                requestManagerEJB.processRequest(dataModel.requestData);
        } else {
                sorryScreen.execute(dataModel);
        }

This was definitively approaching nirvana: flowScript gluing components
across application layers. No misplaced business logic, no cluttered
"controller" logic, absolute separation of concerns.

But then I realized I had to deal with releasing stateful components...

Sylvain and I have addressed the infamous "automatic component
releasing" problem which stems from having to account for continuation
trees. His harsh solution (no components leased at continuation
creation) seems to be the way to go...

If I'm to follow my intutition -and my own experience- I'd bet many
Cocoon developers tend to think in terms of a _single_ outstanding
continuation that reflects the webapp's "expected" flow of execution.
(It was because of such incomplete mindset, btw, that I first thought
acquired components could be automatically released upon sitemap
function completion...)

These and similar experiences suggest web programming with continuations
is an uncharted, brave new world whose deep ramifications we -mere
mortals, non-Lisp gurus- are only beginning to grasp...

Clearly, we need to come up with web-oriented continuation patterns that
reflect real-world application constraints. (Does it make sense to
"reuse" continuations for form validation? How do we implement one-shot
or linear continuations for transactional dialogs with remote servers?)

The core Continuation implementation is superb. The FOM is rapidly
approaching a stable form. The next challenge is understanding how to
take advantage of this tremendous power while avoiding to shoot our
boots.

Just food for thought...


Ricardo









Reply via email to