Re: Weird Behaviour...
Re: Weird Behaviour...
- Subject: Re: Weird Behaviour...
- From: Chuck Hill <email@hidden>
- Date: Wed, 07 Dec 2011 16:22:36 -0800
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@hidden
>>>>>
>>>>> _______________________________________________
>>>>> Do not post admin requests to the list. They will be ignored.
>>>>> Webobjects-dev mailing list (email@hidden)
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>
>>>>> This email sent to email@hidden
>>>>
>>>> --
>>>> 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@hidden)
>>>> Help/Unsubscribe/Update your Subscription:
>>>>
>>>> This email sent to email@hidden
>>>
>>
>> --
>> 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@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
--
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@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden