on 5/27/03 4:19 PM Sylvain Wallez wrote:

> Ok. By "component", I actually meant "instance" obtained by lookup() or 
> getComponent(). Then we have a big problem here : automatic component 
> release is very likely to be handled by the container at special times 
> such as end of request processing. This means the continuation will use 
> released components, thus eventually leading to concurrent access 
> problems since the container is likely to have given the instance to 
> someone else through another lookup().
>
> On the other hand, explicit release like we have today means that the 
> continuation becomes heavyweight since it keeps references to instances 
> that may have been taken out of a pool. And even worse, if a 
> continuation is abandoned we have some leaks since the instance is never 
> released.

Yep. I far prefer the transparent dispose of components and keep them
stateless.

> Mmmh... A solution may be to use the catch(break)/catch(continue) to 
> release components when a continuation is created, and control this at 
> creation time, raising an error if there are still some unreleased 
> components. This should do the job, at the price of important 
> constraints for the flowscript writer.

Like what?

>>Hmmm, I see your point, but let me point something out. In the future, I
>>foresee something like
>>
>><map:flow>
>> <map:script src="block:whatever:/flow/flow.js"/>
>> <map:script src="cocoon:/myDynamicFlow.js"/>
>> <map:script src="myStaticFlow.js"/>
>></map:flow>
>>
>>since we agreed that blocks only expose a URI space controlled by the
>>sitemap (they don't expose resources directly!) you can use a reader to
>>get the flow to the dependent block, or you can use a pipeline to
>>generate your flow (for example, traducing a workflow written using a
>>markup language into the equivalent flow instructions).
>>
>>Here you have all the machinery you need to compose your flows as you
>>like. Recursively.
>>
>>The difference between the above and load() is thin but real: while
>>load() has to be executed at runtime, the <map:script> calls can be done
>>at sitemap assembly time. It could have a big impact on runtime
>>performance of the flowscripts.
>>
> 
> 
> Mmmh... what you're stating here is that we can have "families" of 
> flowscripts (I was about to write "classes") whose contract is defined 
> by the toplevel functions (and hence object classes) they provide, and 
> that a sitemap will assemble its flow script by loading an "instance" of 
> each of the required "families".
> 
> So through it's URI contract, a block will provide not only XML 
> processing services, but also flow code. That's interesting...

Yep and, IMO, incredibly powerful. [also potentially abusable]

I'm aware this might hide some anti-patterns down the road, but I see no
better way of allowing flow composition in a block-based environment.

>>>>------- properties ---------
>>>>
>>>>cocoon.request -> the request object
>>>>cocoon.response -> the response object
>>>>cocoon.log -> the log object
>>>>
>>>>NOTE: the absence of the context object is intentional! we couldn't come
>>>>up with a reasonable need for such an object at the flow level. So, for
>>>>the principle of 'less is more', we don't consider it. Be aware that if
>>>>you want to propose its addition, you have to come up with a reason for it.
>>>>
>>>>     
>>>>
>>>
>>>A simple reason : the context object (the environment one) gives access 
>>>to context parameters defined in web.xml. In many situations, this is 
>>>where parameters depending on the deployment environment are located, as 
>>>it allows the sysadmin to use it's favorite app server GUI to set them 
>>>and avoids editing cocoon.xconf. (yes, I've seen some installs being 
>>>totally screwed up because the sysadmin didn't knew what a well-formed 
>>>XML file was).
>>>   
>>>
>>
>>Ok, this is exactly the real-life good point I was looking for. +1 for
>>adding context.
>>
> 
> :-)
> 
> 
>>Do you need read/write or read-only could be sufficient? (I would go for
>>read-only)
>>
> 
> 
> AFAIK, the only write method is setAttribute(), which can be used to 
> define server-wide data. Considering that flow global variables are 
> bound to the session, this may be useful.

Nah, that's not the answer I like: "may be" is against the concept of
evolutionary design. Either you have a strong reason for it, or it stays
out. ;-)

> <snip/>
> 
>>>>---------------------------------------------------------------------------
>>>>The Log Object
>>>>---------------------------------------------------------------------------
>>>>
>>>>This is a convenience method to access the cocoon logger. It could be
>>>>the same of doing
>>>>
>>>>cocoon.getComponent(...)
>>>>     
>>>>
>>>
>>>Huh ? A logger is not a component.
>>>
>>
>>Why not?
>>
> 
> 
> Huh ? again ;-)
> 
> Or is the notion of component in the FOM different that the one in the 
> other parts of Cocoon ?

Yes and no! a "component" is in the most general sense. It's what Avalon
calls now a "service". or "enterprise bean" if you like (althought I
dislike "bean" because it reminds me of data containers more than
service providers)

> Mmmh... I know you want to avoid abuses, but at the same time, we must 
> not make the flow a strange beast compared to other parts of Cocoon. 
> This is especially important if we want to allow users to migrate big 
> flows to clean Java classes and new components.

nono, no strange beast: just cleaning things up now that we have the
chance to do it.

Avalon is going to deprecate the Component interface because it's too
avalonish and forces people to write thin wrappers just to implement
that interface.

Well, cool, let's blast it. getComponent() returns a java Object and, if
it implements the avalon lifecycle interfaces (or it has avalon
lifecycle metadata somewhere), the component manager will do what it
takes to create it.

In theory, it should be possible to get an EJB directly thru that
getComponent() call. Why not.

This is why I want to keep that "id" general enough and decoupled from
the FOM contract.

> What makes Cocoon so nice is that a few concepts are used to define 
> everything : the Avalon component architecture, a few interfaces (didn't 
> actually count, but I'm sure the main core interfaces are less than 20), 
> and this it. Everything else are implementations built on these few 
> abstractions. So let's be careful and keep the FOM consistent with Cocoon.

I completely agree. In fact, I'm thinking about "removing" some of those
avalon interfaces, not to add others!

> <snip/>
> 
>>Yes. But the problem here is that the sitemap will be come super-verbose
>>since you'll have to add such a transformer all over the place.
>>
>>Well, in my post-2.1 RT on sitemap additions, I will outline the concept
>>of "macro components", basically allow you to create an 'overloaded
>>serializer' which is, in fact, a composition of a transformer and a
>>serializer. Something like
>>
>><map:serializers>
>> <map:serializer name="xhtml">
>>  <map:transformer name="link-translate"/>
>>
> Is it "type" here instead of "name" ?

here yes, sorry.

> 
>>  <map:serializer/> <-- this is the equivalent of super()
>> </map:serializer>
>></map:serializer>
>>
>>NOTE: the above is meaningful in a subsitemap where "xhtml" was already
>>defined, so the above is a "wrapper" around the original component.
>>Alternatively you could have something like
>>
>><map:serializers>
>> <map:serializer name="xhtml">
>>  <map:transformer src="..."/>
>>  <map:serializer src="..."/>
>>
> Again, shouldn't the two "src" above be "type" ?

No, in this case, you define the source of the class that implements
those components but you don't make them available as single components,
but only as aggregated.

> 
>> </map:serializer>
>></map:serializer>
>>
>>where the components that constitute the fragment are not accessible
>>independently, but only aggregated in the macro component.
>>
>>The above removes the magic and increases readability. In fact, it can
>>be applied to all pipeline components (generators, transformers and
>>serializers).
>>
> 
> How is this different from a resource? Resources also allow to define 
> overloaded generators and transformers. So do we really need a new concept ?

I think so because the current sitemap semantics "call" a resource,
while the 'macro component' is simply used inplace.

Look at the difference between:

 <map:resource name="xhtml">
  <map:transformer type="link-translation"/>
  <map:serializer type="xhtml"/>
 <map:resource>

 <map:match pattern="...">
  <map:generate src="..."/>
  <map:transform src="..."/>
  <map:call resource="xhtml"/>
 </map:match>

compared with

 <map:serializer name="xhtml">
  <map:transformer type="link-translation"/>
  <map:serializer type="xhtml"/>
 <map:serializer>

 <map:match pattern="...">
  <map:generate src="..."/>
  <map:transform src="..."/>
  <map:serialize type="xhtml"/>
 </map:match>

Resources were supposed to be reusable pipelines, but *complete* ones!
Later, they were implemented to be usable as pipeline fragments but,
IMO, they impose some readability problems in the sitemap. The above
aims to correct that.

In fact, if the above is introduced, I would deprecate the use of
resources that do not have a complete pipeline.

>>>What about the Avalon context ? Is it omitted on purpose ?
>>>   
>>>
>>
>>yes. do you envision a need for it?
>>
> 
> 
> Don't know... Still my quest for consistency with the other parts of 
> Cocoon ;-)

Remember: symmetry-driven design is a meta-anti-pattern.

Look at biological systems: symmetry never plays an initial role but
it's something that emerges later, if it makes sense to do so. And
nature is much more fractal than symmetrical, because symmetry is a very
weak concept in a noisy environments, unlike autosimilarity. [the
mandelbrot set, for example, looks symmetric but it's not]

So, please, let's try to keep focus on *why* we need something and not
necessarely because it's in place in other parts of the system.

-- 
Stefano.


Reply via email to