Ah…. Now it makes sense.  Thanks for reporting back Ricardo.

From: <webobjects-dev-bounces+chill=gevityinc....@lists.apple.com> on behalf of 
Ricardo Parada <rpar...@mac.com>
Date: Thursday, March 23, 2017 at 2:47 PM
To: Johann Werner <j...@oyosys.com>
Cc: WebObjectsDev <webobjects-dev@lists.apple.com>
Subject: Re: ERXWOConditional - where does it get installed?

Hi all,

I'm reporting back.  I noticed my test app had WOConcurrentRequestHandling set 
to false.  Once I turned it on the dynamic elements started being shared across 
the sessions.

Thanks everyone.

Ricardo


On Mar 21, 2017, at 7:34 PM, Ricardo Parada 
<rpar...@mac.com<mailto:rpar...@mac.com>> wrote:
Thanks Johann.
I'm confused because in my test I was seeing 3 x 5 for #3. Each session had 3 
dynamic elements created.  The dynamic elements started being shared within the 
same session when I started creating multiple instances of the page. All the 
pages in the session started using the same three dynamic elements. But other 
sessions kept on using their own. Each of the 5 sessions was using three.
So I am not sure why I see that behavior and you see only 3 being created.
But if they work as you described #3 then yes I can see trouble big time.
To make things worse I have not found great documentation on how they are used 
by WebObjects. I will take a look at that session that you mentioned.
On Mar 21, 2017, at 6:50 PM, Johann Werner 
<j...@oyosys.de<mailto:j...@oyosys.de>> wrote:
The essence is that a
1) WOComponent is created for every occurrence within a specific page template 
for each session
2) stateless WOComponent is created once for any number of occurrences within 
any page template, additional instances are created if a stateless component is 
currently used by a thread and requested by another one
3) WODynamicElement is created for every occurrence within a specific page 
template
That means that if you have one page where the template uses your component / 
element three times and you are serving 5 users you end up with
1) 3 × 5 = 15
2) 1 ≤ n ≤ 5
3) 3
instances of your component / element. For 1) and 2) you can be sure that 
during a RR-phase you won’t share an instance with multiple threads (unless you 
do some weird things like passing a component instance into a background thread 
or stuff like that). However in case 3) those instances are shared with any 
thread that requests them which can happen at any time during the RR-loop where 
WO does not mind for initialization or cleanup of local values (that is one 
point in making those components fast).
jw
Am 21.03.2017 um 23:18 schrieb Ricardo Parada 
<rpar...@mac.com<mailto:rpar...@mac.com>>:
Was that in a session-less app instance perhaps? I have not tested that 
scenario.
In my test I do not see dynamic elements being shared across sessions, so I'm 
not seeing exactly how is it that concurrency plays a role in the session app 
scenario where the dynamic elements are not shared with the ones from other 
sessions processing a request at the same time.
But again, there may be something else, a property or something that affects 
this sharing that I may be missing.
Anyways, the consensus is that it is a bad idea, so I'll follow advise and 
implement it as a WOComponent subclass instead.
Thank you all.
On Mar 21, 2017, at 5:34 PM, Chuck Hill 
<ch...@gevityinc.com<mailto:ch...@gevityinc.com>> wrote:
I’ve run into code that did this in the past.  It is very, very much not fun to 
debug.  You could stash the values in a ThreadLocal or in the 
context.userInfo().  But don’t ever add state to a WODynamicElement subclass.
Chuck
From: 
<webobjects-dev-bounces+chill=gevityinc....@lists.apple.com<mailto:webobjects-dev-bounces+chill=gevityinc....@lists.apple.com>>
 on behalf of Johann Werner <j...@oyosys.com<mailto:j...@oyosys.com>>
Date: Tuesday, March 21, 2017 at 2:19 PM
To: Ricardo Parada <rpar...@mac.com<mailto:rpar...@mac.com>>
Cc: WebObjectsDev 
<webobjects-dev@lists.apple.com<mailto:webobjects-dev@lists.apple.com>>
Subject: Re: ERXWOConditional - where does it get installed?
Hi Ricardo,
you are ignoring one very important aspect of dynamic components: they must be 
thread-safe!
As soon as you are holding local values you will head to a serious mess. In 
your „manual“ tests of course you probably won’t ever encounter concurrency 
problems as long as you are not doing sort of automated parallel tests where 
multiple request are processed concurrently. Just think about why WO uses 
constructs like WOAssociations in dynamic components which introduce an 
additional layer of complexity to exchange / access request dependent values. 
Surely not for the fun of it ;-)
Of course concurrency problems only show up infrequently and are often not 
reproducible. So depending on the number and activity of your app users you 
could have been just luckily to not run into any problems or—most likely—did 
not notice when you actually hit one of those situations.
jw
PS: If you have access to the recordings of WOWODC 2012 there is actually a 
talk on dynamic elements.
Am 21.03.2017 um 21:11 schrieb Ricardo Parada 
<rpar...@mac.com<mailto:rpar...@mac.com>>:
Hi all,
I’m just reporting back on my findings on whether saving state between 
appendToResponse and a subsequent takeValuesFromRequest in a dynamic component 
is bad or not.
I read Chuck’s Practical WebObjects, p. 193 where it talks about Dynamic 
Elements.  As he pointed out there, dynamic elements are shared among all 
instances of a WOComponent subclass.  My MPVWOConditional is implemented as a 
dynamic element because it extends ERXWOConditional which then extends 
WODynamicGroup which then extends WODynamicElement.
To test this I created a Hello app with a single page, Main.wo.  I have three 
MPVWOConditionals in there.  An instance is created for each occurrence of my 
MPVWOConditional in Main.  A total of three to be exact.
I then have a link on Main that calls an action returning a new instance of the 
page Main:
public WOActionResults newPage() {
    return pageWithName(Main.class);
}
Every time this newPage() action gets called I can confirm that the constructor 
in Main gets called, which indicates that a new page is being created every 
single time this action gets called.
However, the constructor of the MPVWOConditional is not getting called three 
times as when the first/second time the page was created.  On the other hand, 
the appendToResponse() of the MPVWOConditional keeps getting called three 
times, once for every instance of MPVWOConditional in Main.  The hashCode() of 
each of these three MPVWOConditional coincides with the ones that were 
previously created.
To summarize, when new instances of the page are created, the MPVWOConditionals 
are being reused on new instances of the page.
Fortunately, the dynamic components are not shared among page instances from 
different sessions.  Which makes sense.  The sharing only applies among 
instances within the same session.
I can see how some might object to storing this state in the dynamic component. 
 It has worked like this all this time.  It’s the way it works.
However, I think it is okay to save this piece of state between an 
appendToResponse and a subsequent takeValuesFromRequest because the 
takeValuesFromRequest is being done on the same page that generated the 
appendToResponse.
Furthermore, if a new page is created and the components are shared, their 
appendToResponse will get called and this piece of state will be re-computed 
and saved awaiting a subsequent takeValuesFromRequest.
Now, let’s assume that instead of submitting a form, a regular action is called 
on the page.  Let’s suppose this action retrieves the previous page from some 
sort of cache and returns that page.  Then that page’s appendToResponse will 
get called and so will the appendToResponse of the  dynamic components being 
shared, which would recompute the condition and save it awaiting a possible 
subsequent takeValuesFromRequest or invokeAction.  Again, this behavior just 
makes the appendToResponse consistent with the 
invokeAction/takeValuesFromRequest phases.
Having this behavior has corrected problems for me.  It is yet to be determined 
whether this will create a problem.  If I find out later that this creates a 
problem I’ll be happy to report back to the group.
But so far, on my tests, it looks like it is okay.
Thanks for all the comments and feedback.
Ricardo
On Mar 14, 2017, at 10:46 AM, Samuel Pelletier 
<sam...@samkar.com<mailto:sam...@samkar.com>> wrote:
Ricardo,
This patch seem dangerous to first. I do not thing it is safe to have state in 
WODynamicElement. I think they can be reused by the framework.
The correct way is to make sure the condition does not change during RR loop 
cycle, same apply to WORepetition list for example.
Regards,
Samuel
Le 14 mars 2017 à 09:53, Ricardo Parada 
<rpar...@mac.com<mailto:rpar...@mac.com>> a écrit :
Thanks Samuel.  I see that now.
Have others experienced a problem where a form is submitted and then during 
takeValuesFtomTequest a condition that was false when the page was rendered 
becomes true all of a sudden causing some input elements (textfields, pop-up 
list, etc.) to participate in takeValuesFromRequest even though those elements 
were not on the page when the form was submitted? This causes those elements to 
be set to null.   I've ran into such bugs in the past many times.
I have been able to prevent that from happening by using the following code:
public class MPVWOConditional extends ERXWOConditional {
   protected boolean conditionValue = false;
   public MPVWOConditional(String name, NSDictionary dict, WOElement element) {
      super(name, dict, element);
   }
   @Override
   public void appendToResponse(WOResponse woresponse, WOContext wocontext) {
      // Cache the condition every time the page is being rendered
      conditionValue = 
_condition.booleanValueInComponent(wocontext.component());
      super.appendToResponse(woresponse, wocontext);
   }
   /**
    * Returns the value for the condition binding cached during 
appendToResponse.
    * This makes the takeValuesFromRequest consistent with the appendToResponse
    * preceding it by making sure that input elements that were not present on
    * the page at the time the form was submitted do not participate in
    * takeValuesFromRequest inadvertently.
    */
    @Override
    protected boolean conditionInComponent(WOComponent wocomponent) {
       return conditionValue;
    }
}
On Mar 14, 2017, at 9:39 AM, Samuel Pelletier 
<sam...@samkar.com<mailto:sam...@samkar.com>> wrote:
Hi,
If you use inline bindings with ONGL, the class WOHelperFunctionTagRegistry 
registers classes mapped to tag
                   WOHelperFunctionTagRegistry.registerTagShortcut("ERXElse", 
"else");
                   
WOHelperFunctionTagRegistry.registerTagShortcut("ERXWOConditional", "if");
                   
WOHelperFunctionTagRegistry.registerTagShortcut("ERXWOConditional", 
"conditional");
Samuel
Le 13 mars 2017 à 19:46, Ricardo Parada 
<rpar...@mac.com<mailto:rpar...@mac.com>> a écrit :
Hi all,
Does anybody know where does ERXWOConditional install to replace WOConditional?
I created an MPVWOConditional which extends ERXWOConditional and fixes a bug 
and want to install it as the one to use for WOConditional.
I checked in ERXPatches but it does not seem to be getting installed there.  
Does anybody know?
Thanks
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      
(Webobjects-dev@lists.apple.com<mailto:Webobjects-dev@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/samuel%40samkar.com
This email sent to sam...@samkar.com<mailto:sam...@samkar.com>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      
(Webobjects-dev@lists.apple.com<mailto:Webobjects-dev@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/jw%40oyosys.com
This email sent to j...@oyosys.com<mailto:j...@oyosys.com>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      
(Webobjects-dev@lists.apple.com<mailto:Webobjects-dev@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/rparada%40mac.com
This email sent to rpar...@mac.com<mailto:rpar...@mac.com>


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      
(Webobjects-dev@lists.apple.com<mailto:Webobjects-dev@lists.apple.com>)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/chill%40gevityinc.com

This email sent to ch...@gevityinc.com<mailto:ch...@gevityinc.com>
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to