On 2011-12-07, at 2:22 PM, Ramsey Gurley wrote:
> On Dec 7, 2011, at 2:30 PM, Chuck Hill wrote:
> On 2011-12-07, at 8:01 AM, Ramsey Gurley wrote:
>>> On Dec 6, 2011, at 3:43 PM, Chuck Hill wrote:
>>>> On 2011-12-06, at 2:31 PM, Lachlan Deck wrote:
>>>>> On 07/12/2011, at 9:23 AM, Philippe Rabier wrote:
>>>>> 
>>>>>> I can feel how uncomfortable you are. 
>>>>>> 
>>>>>> What makes me confused is to never see this bug before. It's hard to 
>>>>>> believe that nobody saw the errors if there are error. But on another 
>>>>>> side, I (and all the team) worked on many applications  so following the 
>>>>>> explanation, I don't know why we don't see this issue much more often. 
>>>>> 
>>>>> I suspect the more prevalent use of concurrent requests these days has 
>>>>> exposed this bug.
>>>> 
>>>> It is worth carefully reading over the reproduction steps:
>>>> 
>>>>>      * How it fails: A request is handled by WorkerThread0. By the end of 
>>>>> the request the eo has been modified but not saved, so the 
>>>>> EOObserverCenter remembers
>>>>>      * that WorkerThread0's most recent object is that eo. Fifteen more 
>>>>> requests are handled by WorkerThreads 1-15 in sequence. One of these 
>>>>> requests completes
>>>>>      * the modification of the eo and calls saveChanges on the ec. At 
>>>>> this point the ec tells the EOObserverCenter to forget about its most 
>>>>> recent object, but
>>>>>      * it's being set to null in WorkerThread14 or whatever, not 
>>>>> WorkerThread0.
>>>>>      *
>>>>>      * The next request will wrap around to to be handled by 
>>>>> WorkerThread0. This request modifies an attribute on the eo, but since 
>>>>> the EOObserverCenter still
>>>>>      *  thinks WorkerThread0 has already noticed the eo, it ignores the 
>>>>> willChange and the ec doesn't grab a snapshot.
>>>>>      *
>>>>>      * Later in the processing of this request, a different object gets 
>>>>> changed, willChange gets called and the ec grabs a snapshot of the second 
>>>>> object. Then,
>>>>>      * a change gets made to the original eo, willChange gets called, and 
>>>>> since the EOObserverCenter was paying attention to the second object, it 
>>>>> goes ahead
>>>>>      * and notifies the ec about the first object.
>>>>>      *
>>>>>      * At this point the ec grabs a snapshot of the first object, but 
>>>>> it's too late -- the object has already been modified, the ec didn't know 
>>>>> about the
>>>>>      * previous change, so when saveChanges gets called the previous 
>>>>> changes don't get saved to the database. And now your object graph no 
>>>>> longer matches the
>>>>>      * database, and your app is borked.
>>>> 
>>>> 
>>>> Note that it has to be the _same_ eo (same GID) and the same thread and it 
>>>> has to be in a modified but unsaved state.  
>>> 
>>> In EOObserverCenter I see:
>>> 
>>> eo == threadInfo._lastWillChangeObject
>>> 
>>> Same ec, multiple threads.. oy!  
>> 
>> Not sure what is concerning you there.  _lastWillChangeObject is just a 
>> performance optimization to avoid sending repeat, identical notifications.  
>> I don't think it is getting used by two threads at once, at least not in the 
>> sense of needing to be locked.
> 
> Oh, no, I'm sure it's okay.  It just that it goes against the general advice 
> of never passing EO's across threads, only GIDs.  I know it's okay in this 
> case because it's Apple internal, locking is handled elsewhere, and they are 
> generally just much smarter than me...  
> 
> Still, I cringe ;-)  It's like a reflex.
> 
> 
>>> It stands to reason that when the ec is saved, any eo in that ec should be 
>>> removed from the threadInfos.  It sounds like the _ThreadInfo should set up 
>>> an observer on the ec's EditingContextDidSaveChangesNotification.  Once 
>>> saved, any threadInfo with an eo in that ec should set 
>>> _lastWillChangeObject to null.
>> 
>> I think you will find that the EC is already handing this.  
> 
> For the current thread only though, right?  I could see how one thread might 
> edit EO1, thread2 edits EO2 related to EO1, Thread3 edits EO1 again and 
> finally saves the EC.

You are gonna keep yourself up at night thinking things like that.


> Now the EC sends notify(null) to the EOObserverCenter and clears the 
> ThreadInfo on thread3, but thread1 and 2 are unaware.  If threadInfo set up a 
> notification then every threadInfo would be notified of the save and thread1 
> and 2 would clear too.

But threads 1 and 2 don't need to be aware as they are working with a different 
EC at that point.  The problem is that the performance optimization is not 
getting reset at the correct time.


> At least that's the way I read the problem description.
> 
>> The issue arises when the EO is modified but NOT saved during the RR loop.  
>> What is missing in WO vs YellowBox is a fully built out concept of an event 
>> loop.  There is no clear, common "event ended" for the RR loop where this 
>> would normally be set to null.  There are notifications that could be 
>> caught.  The end of dispatchRequest() is a reasonably good place to do this.
> 
> Okay, so I've got this <FRAMESET> and all 12 frames are modifying an EO from 
> the defaultSessionEC ... :-D  Maybe reimplementing EOObserverCenter is 
> over-engineering the problem, but if I do any event driven stuff outside of 
> the RR loop using... say ... websockets, I'll need to remember to do the same 
> there.

Yes, if you are re-using threads and ECs between requests.  And you would still 
have some sort of RR loop.

Chuck



>>> I wonder what about nested ECs?  Let's say the parent ec is saved, but the 
>>> nested ec has changes to an EO already. What then?
>> 
>> If it has changes, it has already gotten a "original snapshot" and has 
>> merged in the parent's saved changes.  
> 
> Okay, that's the part that I wondered about.  I assumed this would be the 
> case, but I've never done enough digging to see exactly where it happens.
> 
>> Also remember that the eo in the parent is not instance equal (==) to the eo 
>> in the child so EOObserverCenter sees them as totally different objects.
>> 
>> 
>> Chuck
> 
> Alright, lets add it to Wonder. Problem solved. The rest is academic at this 
> point ;-)
> 
> Ramsey
> 
>> 
>> 
>>>> My guess is that unless your users are doing highly concurrent editing of 
>>>> the same data that this will rarely affect you.  That is why I found it 
>>>> fixing Calven's problem so readily a surprise.  
>>>> 
>>>> 
>>>> 
>>>>>> And a question regarding the workaround: is there any drawback to call 
>>>>>> the EOObserver in the dispatchRequest method like suggested?
>>>>> 
>>>>> For multiple active worker threads, a good question... 
>>>>> 
>>>>> Lachlan Deck
>>>>> [email protected]
>>>>> 
>>>>> _______________________________________________
>>>>> Do not post admin requests to the list. They will be ignored.
>>>>> Webobjects-dev mailing list      ([email protected])
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>> http://lists.apple.com/mailman/options/webobjects-dev/chill%40global-village.net
>>>>> 
>>>>> This email sent to [email protected]
>>>> 
>>>> -- 
>>>> Chuck Hill             Senior Consultant / VP Development
>>>> 
>>>> Practical WebObjects - for developers who want to increase their overall 
>>>> knowledge of WebObjects or who are trying to solve specific problems.    
>>>> http://www.global-village.net/products/practical_webobjects
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list      ([email protected])
>>>> Help/Unsubscribe/Update your Subscription:
>>>> http://lists.apple.com/mailman/options/webobjects-dev/ramseygurley%40gmail.com
>>>> 
>>>> This email sent to [email protected]
>>> 
>> 
>> -- 
>> Chuck Hill             Senior Consultant / VP Development
>> 
>> Practical WebObjects - for developers who want to increase their overall 
>> knowledge of WebObjects or who are trying to solve specific problems.    
>> http://www.global-village.net/products/practical_webobjects
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list      ([email protected])
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/webobjects-dev/rgurley%40smarthealth.com
>> 
>> This email sent to [email protected]
> 

-- 
Chuck Hill             Senior Consultant / VP Development

Practical WebObjects - for developers who want to increase their overall 
knowledge of WebObjects or who are trying to solve specific problems.    
http://www.global-village.net/products/practical_webobjects







Attachment: smime.p7s
Description: S/MIME cryptographic signature

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to