cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Reinhard Poetz <reinh...@apache.org>
Subject Re: Blocks, Flow and Dependencies
Date Thu, 13 Jan 2005 16:00:39 GMT
Daniel Fagerstrom wrote:
> Stefano Mazzocchi wrote:
> 
>> Reinhard Poetz wrote:
>>
>>>>> Answer: It depends on the order of declaring your scripts in 
>>>>> <map:flow/>. The first helper() method declared will be found.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> But there is only one helper() method per block!?
>>>
>>>
>>>
>>>
>>> Yes. Therefore we need something more sohpisticated than imports.
>>
>>
>>
>> I'm having a hard time following this conversation, as it seems to me 
>> that this is another instance of something that is becoming an 
>> anti-pattern: "stating the solution before stating the problem".

I agree but as Daniel explains below, we first had the problem. Maybe you gave 
them a better headline (delegation) and you found a second problem problem that 
could be relevant in this context: extension

> The problem that we discuss was stated by Reinhard in 
> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=110519369529959&w=2, 
> and then discussed in the rest of that thread 
> (http://marc.theaimsgroup.com/?t=110467878200001&r=1&w=2). Glen changed 
> name of the thread to something more relevant for the topic and we 
> continued to discuss it 
> http://marc.theaimsgroup.com/?t=110533379600002&r=1&w=2. I tried to 
> explain the issues and point to the use case in 
> http://marc.theaimsgroup.com/?t=110533379600002&r=1&w=2 again, as a 
> service to newcommers to the discussion, and make a new trial explaining 
> the issues below.
> 
>> The problem is that you want to use some functionality defined in 
>> another block.
>>
>> Fair enough, since that's what blocks are: isolated service providers.
>>
>> One of the design decisions with blocks is that *NO FILE* will ever be 
>> exposed by the blocks directly.
>>
>> There is practically no way in the world you are going to change my 
>> mind on that, so consider it a permanent -1 for a block to expose 
>> direct file access.
> 
> 
> I agree completely with that, and have discussed how to achieve 
> shielding of block internals earlier in the thread.
> 
> Usecase
> =======
> 
> Now the use case that Reinhard and I have discussed is:
> 
> The idea is that I in a number of my webapps want to use the same 
> handling of new customers. And therefore I have written a block 
> "Customer" containing among other things  a flowscript function:
> 
> function newCustomer() {
>  var customer = new Customer(defaultCustomer.xml);
>  cocoon.sendPageAndWait("nameAndAdress");
>  ...
>  cocoon.sendPageAndWait("preferences");
>  ...
>  cocoon.sendPageAndWait("spamPreferenses");
>  ...
>  return customer;
> }
> 
> That handles a dialog with a new customer and returns an object that 
> contains the result of the interaction.
> 
> Then we might want to use this functionality in another block for 
> e-business that among other things uses the newCustomer function. That 
> could e.g. look like:
> 
> function buy() {
>  ...
>  var customer = newCustomer();
>  ...
>  cocoon.sendPageAndWait("shoppingCart");
>  ...
> }
> 
> IMO this is a relevant use case for blocks and flow.
> 
> Several Contexts
> ================
> 
> After having seen the use case the question is what to do about it. 
> First it is important to note that Customer:newCustomer() contain a 
> number of references to resources within the Customer block: the file 
> defaultCustomer.xml and the possibly internal pipelines nameAndAdress, 
> preferences, spamPreferenses. A consequence of this is that even if the 
> function is executed in the context of another block, like the 
> e-business block above, all its relative URIs must be resolved in the 
> context of the Customer block.
> 
> So using flowscripts from other blocks is more complicated that using 
> flowscripts from the same block (the current situation). When using a 
> flowscript from the same block you just call it in the current context 
> that is descripbed by the FOM. When you use a flowscript from another 
> block it must be exectuted in the context of the "FOM" from the other 
> block. So the situation is like in object oriented programing the block 
> is an object and the flowscript function is a method on it.
> 
> Sylvain have recoginzed that the handling of block (and sitemap) 
> specific contexts is necessary for implementing VPCs and blocks, and 
> discussed the concepts and its implementation in 
> http://marc.theaimsgroup.com/?t=110064560900003&r=1&w=2. I have sugested 
> that this can be interpreted in terms of static and dynamic binding, a 
> refinement of the parameter passing strategy and polymorphic sitemaps in 
> that thread.
> 
> Implementation Approaches
> =========================
> 
> Returning to implementation of the usecase above. We have discussed some 
> solutions, it can be solved by calling the flowscript function in a VPC 
> pipeline defined in block. This VPC pipeline can then be used in other 
> places following Sylvains design. We need some slightly modificated 
> cocoon.sendPageAndWait function that handles foreign VPCs. This is the 
> solution that I initially and Glen more persistently proposed.
> 
> The problem with that solution is how to pass the return value. It could 
> be done by seting a session variable from the flowscript variable, but 
> neither I nor Reinhard liked that solution. Communication between 
> components by using global variables is not my favorite way of building 
> systems. It scales badly, the communication between components becomes 
> rather implicit and we have a risk that different blocks gets session 
> variable name collisions.
> 
> Another solution would be to introduce some kind of return value for VPC 
> pipelines and a third would be package the exported flowscript function 
> as some function like thing that is easy to use from flowscripts. 
> Reinhard and I have discussed the third option.
> 
> Here there are a number of questions:
> 
> * How to export functions from blocks. My opinion is that they should be 
> explicitly enumerated in the VPC section is the block
> 
> * How to use them from another block, provided that they are exported. 
> Reihnard proposed: cocoon.block.Customer.newCustomer();, which I find a 
> good solution as it solves the problem that the function must be called 
> in the context of its block. It solves the problem with lack of name 
> spaces in JS and it also showes the object oriented nature of the 
> situation.
> 
> * How to implement it.
> 
> * Other shielding issues. E.g. what about the web continuations that are 
> created during the execution of a block flowscript: 
> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=110537204229024&w=2
> 
>                                                          --- o0o ---
> 
>> Blocks *may* expose their sitemap pipelines but nobody said that they 
>> couldn't expose flow functions too (which are the flow equivalent of 
>> sitemap pipelines)
>>
>> Now, blocks have different composition patterns:
>>
>>  - dependency
>>  - extension
>>
>> the two will, IMO, result in different ways of composing flow functions.
>>
>> Dependency can make available, either implicity or explicitly thru a 
>> cocoon.importDependencies() the block's dependencies.
>>
>> Since javascript has no notion of "private/public" for functions, we 
>> could specify that functions that start with _ are "private", while 
>> the other ones are "public". Or something like that.
>>
>> For extension, we could have automatic overload, so that if block A 
>> has flow with function blah() and block B extends block A with 
>> function blah() you can do
>>
>>  block b:
>>   blah() {
>>    cocoon.super()
>>    print "blah b"
>>   }
>>
>>  block a:
>>   blah() {
>>    print "blah a"
>>   }
>>
>> if block b extends block a, calling blah() on b will result in
>>
>>  blah a
>>  blah b
> 
> 
> These are certainly also important use cases.
> 
>> There is *NO* need for direct file access and there is
> 
> 
> Agree
> 
>> *NO* need for namespaces in javascript.
> 
> 
> Combining blocks from several manufacturers will be more complicated if 
> there are name collsions. But by using the exported functions as a 
> method on the "block object", that problem disapears.
> 
>> I understand the above might not be easy to implement, but 
>> implementation difficulty should *never* drive design decisions.
> 
> 
> I tend to live after that policy, but my employers have not always been 
> happy with that approach ;)

;-)

I think this mail is a very good summary of the current status of our discussion 
  about how inter-block flowscript communication should look like.

-- 
Reinhard

Mime
View raw message