cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Hunsberger <>
Subject Re: [RT] function sources
Date Wed, 24 Nov 2004 21:16:21 GMT
On Wed, 24 Nov 2004 12:15:27 -0800, Miles Elam <> wrote:
> On Nov 24, 2004, at 7:31 AM, Peter Hunsberger wrote:
> > On Tue, 23 Nov 2004 12:16:16 -0800, Miles Elam <>
> > wrote:
> >> Yes.  The "src" attribute is a String.  What you do with that String
> >> has always been implementation dependent.  It's just that the
> >> implementation has always (?) been to use the SourceResolver
> >> exclusively.
> >
> > I think that others are saying you can do your proposal by having the
> > source resolver understand a "script" source, which makes sense to me.
> >  IOW, really you just need to wrap the return from script engine to
> > that it can look like  a source and you've got what you want.  So, it
> > continues to exclusively go to the SourceResolver.  But this isn't the
> > complete answer, read on...
> Yes, Vadim's suggestion has definitely rubbed me the right way.
> > Note that, so far, having a scriptable source hasn't removed any need
> > for continuations because it doesn't address the issue of mapping the
> > source to the action.  To do this you'd need a new concept even beyond
> > sources, which I think is what you're trying to get at?
> I'm a little confused as to where you're going with this so I am
> hesitant to comment authoritatively.  Sources have thus far been given
> a string, it's been processed, and a data chunk has been returned.  

Right, you haven't gotten rid of continuations in any way...

> I
> don't see that model changed by the addition of a script source.  What
> is required after looking into it is a change to the Interpreter
> interface, FOM_JavascriptInterpreter class, and the addition of an
> alternate to FOM_Cocoon.  As much as this might seem for a pet feature,
> it is actually not that bad.
> In addition to the existing method:
>     void callFunction(String funName, List params, Redirector
> redirector)
> I propose the following variant be added to codify/enforce this new
> contract:
>     Object callFunction(String funName, List params)
> Whether it should be an Object return value (what is returned from the
> script function) or Serializable or ScriptableObject, I'm not sure.
> But it is my opinion that the script source should *absolutely not*
> break the pipeline viewpoint.  To do so would be extremely intrusive
> the existing design and codebase.  More on this last point later.

If you're fine with just having the scriptable source that's ok by me,
but in your original post part of your motivation seemed to be to get
rid of having to code a second sitemap fragment that wasn't obviously
glued to the original sitemap invocation of the flowscript.  Just
having a scriptable source doesn't solve that unless you're willing to
go back to using actions?

> > Let's consider this second thing; what you'd need is some new source,
> > lets call it "continuable-script".  Then in your sitemap you'd do:
> >
> > continuable-script:myfunc(...)
> Oh for the love of God, no!  Explaining later.
> > I think this makes some sense, but what you're asking for is more than
> > a source.  You're asking for a transparent hook into continuations
> > handling that eliminates the need for a second sitemap fragment, but
> > does not eliminate continuations.
> No no no!  I want no part of continuations *at all* in this proposal.
> I'm suggesting that the existing interpreter handling be used, but the
> processing model would not include continuations in the equation.
> Coming up on the full explanation now.
> > I'm not sure I'd want any kind of magic default handling either, I was
> > just throwing the idea out to see if it had any resonance with the
> > rest of the issue.  Now that I think I've got the entire concept of
> > what you're asking for I think your idea is a little cleaner.
> Okay.  To clarify, adding support for calling a code path with
> continuations would have so many unintended consequences, it boggles
> the mind.  Let's say the script source is invoked from a transformer.
> If sendPageAndWait was called in the code, not only the programming
> stack must be serialized/persisted but the current status of the active
> pipeline up until the transformer in question.  What happens if the
> generator hasn't already finished sending it's SAX events?  What
> happens if the pipeline has already started sending data before the
> script function is called?  How do you restore state in arbitrary
> sitemap components.  Such a headache with little to no return on
> investment.

You missed the point here: the continuation isn't invoked immediately.
 It's invoked after serialization of the pipeline is complete.  The
"sendSource" function signals that this chunk of script has finished
creating some source object and is ready to hand it back to the
regular pipeline processing.  Now the pipeline resumes process as
normal except after serialization is completed you finish off creating
the dangling continuation.  The pattern becomes:

        <map:match pattern="*/foo/*">
            <map:aggregate element="wrapper">
                    <map:part src="cocoon:/{../1}/bar"/>
                    <map:part src="scriptable-source:myfunc({2})"/>
            <map:transform src="stylesheets/blxsl"/>
            <map:transform src="stylesheets/uixsl"/>
            <map:serialize type="xml"/>

where the scriptable source looks like:

function myfunc( srcname )   {
var sourceBuilder =;
var source = sourceBuilder.create( srcname, cocoon );  // Or such 
sendSource( source, params );   // Waits for continuation to complete

The "sendSource" doesn't immeaditely invoke the continuation.  Sorry
if I didn't explain this better but I assumed this was what you where
really after...  The benfit is that you now have a clear single
mapping of single pipeline fragment to single script fragment.

The ability to stack multiple sources into this mess really (via
aggregate or by sending them to a transform) doesn't really change
things, except that you've now got scripts wrapping scripts and
keeping things straight could get complicated.   Thus I should make it
clear you want both sendSource and a regular "return object" path out
of the script.  If you need multiple things on the return then maybe
you end up with sendSource and sendSourceAndWait (where the latter
assumes the semantics I've described to this point).

Thinking about it this points out you only need "script" as a source,
since the decision to invoke the continuation is made in the script
(sendSource vs. return). continuable-script isn't needed...

> This means that sendPage, sendPageAndWait and even redirect-to *must
> not ever* appear in the codepath.  In addition, I'm finding that access
> to the response object should be restricted as well.  I'm on the fence
> about setting cookies too.  Session data is open season though with the
> exception of invalidating the session altogether.  Once again, hidden
> side effects.
> In the end, I'm aiming for a solution where looking at the sitemap
> tells you exactly what's going on from a high-level perspective.  I
> definitely do not want to jeopardize this management contract.  The
> script source gets invoked, it gets its data, it returns the data to
> the pipeline component and normal pipeline processing resumes
> uninterrupted.

Yes, I agree and that's what I want also.  What I think you're leaving
out is the action handling side of things?  If you don't want
continuations you've got to have actions.  Just sending a source to a
pipeline doesn't get rid of continuations?

> > I meant implementation point of view.  With the new concept I'm not
> > sure you've separated concerns since now a single script has the
> > responsibility of producing both the source and then handling the
> > action upon return.  I don't really have a problem with this, maybe
> > others will?
> How so?  What I'm proposing basically just says, "Give me data."  The
> pipeline is still responsible for what gets returned to the client.  Or
> were you referring to the fact that they both call the same JavaScript
> source files specified in the <map:flow> sitemap directive?  If so, I
> think separating them at that level would introduce more hardship, not
> lessen it.  I'm all about lessening hardship.

Yes, I was referring to the fact that you might have just a single
JavaScript file.  As I said I don't see a real problem with this...

> > I think the complete implementation as I've sketched out is a tad
> > harder than just a source wrapper around a script produced object!  I
> > still think it sounds doable, but I've been through some of this code
> > and it it takes a lot of little turns and twists and this wouldn't
> > make it any simpler!
> Looking closer at the problem, I see the following changes necessary:
> 1. Script source resolver parses function call and arguments and passes
> them to...
> 2. An Interpreter method call that does not include a redirector
> where...
> 3. Processing this call neglects to put in any continuation plumbing
> normally associated with it and...
> 4. Instantiating a stripped down clone of FOM_Cocoon that does not have
> continuation, response or sendPage* handling (a SOM_Cocoon/Scripting
> Object Model if you will) which is then...
> 5. Passed to the JavaScript engine for processing to do the actual work
> and return a value to...
> 6. The script source which exposes the returned object (Object
> reference or InputStream?) to the pipeline component
> The rest of the code seems to be there already.  When the script
> function only has the functionality necessary to do what is expected,
> the contract is enforced.  Accidental sendPage and redirect-to calls
> would result in runtime errors just like any call to a non-existent
> variable/function.  Return statements in "normal" flow function return
> an error.  Fail fast.  Fail loudly.  Fail clearly.

I'm still missing how you handle POST actions?

> >>>> 4. Could the same flow engine be used but with a different set of
> >>>> default objects/interfaces?
> >>>
> >>> I think so.
> >
> > Yes, in fact you'd want almost exactly today's code for the
> > implementation I describe, you basically just break sendPage into two
> > parts, one handled at "sendSource" time and the other when the
> > serializer terminates.  I have no idea how to glue the two pieces
> > together over the duration of the sitemap traversal of the rest of the
> > pipeline (or if it' really possible); I think it's some kind of
> > context stack but you need a pipeline expert to answer that question.
> Ah!  Now I see the difference in our approaches/expectations.  You are
> assuming that the flow interpreter is in charge.  For standard flow, I
> agree that it is.  For my examples, I've been working under the
> assumption that it is not.  I'm making calls to a scripting interpreter
> for the duration of a function call, but the sitemap never truly
> relinquishes control.  The pipeline processing asks for data from the
> interpreter, and when that data is received, the pipeline resumes.  No
> sendPage/sendSource clones.  The called function returns useful data or
> it doesn't.  That amounts to a return statement.  No fanciness or
> special handling required at all.

Right, that's Vadm's simple plug in for source generation via a
script.  That doesn't get you everything you asked for in your
original e-mail...

> -----
> Oh!  Here's an issue.  How and where does the script source get a
> reference to the interpreter?  It would be dependent upon the
> sitemap/subsitemaps and their respective flow declarations.  Where does
> the handoff take place?

Now you're jumping into a completely different issue: the discussion
of relative/absolute URI resolution and subsitemaps and VPC's.  I'd
just assume that that get's ironed out in accordance with some of the
recent discussions and let the sitemap engine handle the invocation as
it sees fit? That is, sitemaps already know how to call the

Peter Hunsberger

View raw message