Re: Idea: EOEditingContextGroup
Jonathan Rochkind <[email protected]>
| Newsgroups | gmane.comp.web.webobjects.eof |
|---|---|
| Message-ID | <[email protected]> |
I've been thinking of similar stuff, except in regards to nested ECs rather
than peer, since that's what I mostly use. But the problem and the
potential solution are similar.
The problems I've run into in the past when thinking about/implementing
these types of things have to do with retainment and garbage collection.
At least prior to WO 5.2, it was _disastrous_ if an EC lock()ed, and then
was garbage collected without being unlock()ed. Because the EC.lock() also
took out a lock on lower EOF stack objects, so those locks would
remain. This may no longer be true in 5.2, but since it wasn't even
documented that way pre-5.2, and since it could again change in the future,
it seems important to ensure that any EC that takes out a lock _always_
unlocks. [This has implications unrelated to memory and GC, but I'm not
concerning myself with those at this moment].
Your implementation doens't seem to bring up these problems. Becuase the
Session object keeps a reference (an ordinary 'strong' reference) to all of
the peer ECs. That means that once a peer EC is created, and registered
with the Session as it must be, that peer EC will NEVER be GC'd. It will
exist forever. Is this acceptable to your design? It may be, if you
implement some 'pooling' system for peer ECs---when a peer EC is needed,
you can ask the Session for one, and you'll get an available one, or the
Session will create a new one for you. Or maybe your design doesn't even
need this, but is fine for other reasons with peer ECs never being garbage
collected.
But ECs are expensive objects. Partially in terms of memory---although WO
5.2 seems to improve this somewhat, becuase an EC will only strongly-retain
EOs if they have pending changes. But also becuase an EC that exists will
continue to recieve and act upon various notifications sent by the EOF
stack. I think it would be undesirable to have hundreds (or even dozens)
of ECs hanging around per-session, that aren't really ever going to be used
again.
I'm interested in your comments on these concerns, and how they effect your
design.
At 07:30 PM 12/18/2002 +0100, David Teran wrote:
>Hi,
>
>i just had a short discussion with wojtek about nested and peer ec. I had
>the following idea to automatically lock and unlock peer ecs:
>
>1) A EOEditingContext subclass overrides lock and unlock
>2) set this ec to be the default ec from the session
>3) session should know ever peer ec (register the ec in an array / collection)
>4) when session sends lock and unlock to its defaults ec the default ec
>will either post a synchron notification or just tell the session back to
>lock / unlock every peer ec in the sessions array / collection
>
>Does someone see any problem with such a feature except that one uses a
>custom ec? Just wrote the concept things down in the mail but i did not
>test the code. Of course some things are still missing, this is just a
>concept and not a working class.
>
>regards david
>
>public class C9EditingContext extends EOEditingContext {
>
> public C9EditingContext() {
> super();
> }
>
>public void lock() {
> super.lock();
> //post synchron lock notification here
>}
>
>public void unlock() {
> super.unlock();
> //post the synchron unlock notification here
>}
>}
>
>public class Session extends WOSession {
>
> private NSMutableArray ecs = new NSMutableArray();
>
> public Session() {
> super();
> setDefaultEditingContext(new C9EditingContext());
>}
>
>//method gets called when the locked notification is received
>public void lockedEc() {
>for (Enumeration e = ecs.objectEnumerator(); e.hasMoreElements();) {
> EOEditingContext ec = (EOEditingContext)e.nextElement();
> ec.lock();
>}
>}
>
>//method gets called when the unlocked notification is received
>public void unlockedEc() {
>for (Enumeration e = ecs.objectEnumerator(); e.hasMoreElements();) {
> EOEditingContext ec = (EOEditingContext)e.nextElement();
> ec.unlock();
>}
>}
>
>On Saturday, Jul 6, 2002, at 03:04 Europe/Berlin, Max Muller wrote:
>
>>Hi,
>> One of the legacy issues that EOF has maintained since being
>> built solely for the desktop is the notion of always propagating changes
>> to all of the existing editing contexts for a given objectstore
>> coordinator. This leads to the behavior that if two people are editing
>> the same eo in two different sessions then they could see each others
>> changes if they are on the same app instance and not see each others
>> changes if they are not on the same app instance. By "see each others
>> changes" I mean that if one successfully saves then the changes will be
>> propagated into the others editing context. This behavior is not ideal
>> as multiple instances can cause optimistic locking failures. One
>> solution is to use a delegate and disable all propagation of changes
>> between editing contexts, this however sucks because then you can't use
>> peer contexts to edit or create eos. Another solution is to give each
>> session it's own complete EOF stack, this one also sucks because in
>> doing this you add *way* too much overhead which will eat memory like
>> you wouldn't believe if you had say 1,000 sessions active. So how about
>> adding an EOEditingContextGroup that you could then use to control the
>> propagation of changes to only those editing contexts within the group?
>> This way each session would have it's own ec group which the
>> defaultEditingContext would be a member of, new peer contexts could also
>> be added to the group so that changes occurring in those contexts would
>> propagate to the default ec.
>>
>> The only difficult aspect would be "knowing" if an optimistic
>> locking failure occurred within the same application. Right now all of
>> the snapshots are held at the database context layer. Once one session
>> had updated an object (say setting Person's firstName to "Scott") then
>> the snapshot reflects this new value. However if those changes have not
>> been propagated to another session that has changes to the same eo then
>> by default if they attempt to save and *are* on the same instance the
>> save will go through, if they are not on the same instance the save will
>> fail (assuming locking). What I am wondering is how to make sure that
>> the save within the same application fails as well. One approach would
>> be for the eo itself to "know" it's committed snapshot and then the ec
>> could compare the eo's committed snapshot against the databasecontext's
>> snapshot for the object and potentially throw the optimistic exception.
>> I don't think that this is the best approach, anyone else have any
>> thoughts? How would you implement this (or not ;)? Is the idea of ec
>> groups a good one?
>>
>>Regards,
>> Max
>>
>>ps - As a side note I would also like to provide an optimistic locking
>>resolver interface that could be registered on a per entity basis that
>>could intercede if a locking failure occurred and potentially prevent an
>>actual exception from being thrown. In other words being able to use
>>different policies for locking failures depending on the business case
>>and also being able to throw your own type of locking exception.
>>
>>
>>_______________________________________________
>>EOF mailing list
>>[email protected]
>>http://www.omnigroup.com/mailman/listinfo/eof
>>
>---
>cluster9, David Teran
>
>Juedenstrasse 13
>37073 Goettingen
>Germany
>
>Mail: [email protected]
>Phone: +49 (0) 551 48 83 077
>Fax: +49 (0) 551 48 83 079
>
>_______________________________________________
>EOF mailing list
>[email protected]
>http://www.omnigroup.com/mailman/listinfo/eof