Re: slooow delete

Sebastien Bigaret <[email protected]> Fri, 18 Mar 2005 12:18:57 +0100
Newsgroups gmane.comp.python.modeling
Message-ID <[email protected]>
John Lenton <[email protected]> wrote:
> On 11 Mar 2005 22:19:37 +0100, Sebastien Bigaret
> <[email protected]> wrote:
> >=20
> > *Big fat warning* (!): do that if you're absolutely sure that
the
> >     related 'need', 'team' and 'mealType' objects are not
already
> >     fetched in other ECs, *or*, if they are fetched, that the
"inverse"
> >     tomany faults are not cleared.
>=20
> If I read you correctly then I'm safe, because I never do
>=20
>     need.setTasks(None)
>=20
> (is this what you mean by clearing the tomany faults?)


My apologize John, I'm afraid I was not clear (!) at all, too
much
jargon I guess.  What I meant by "clearing the fault" was the
same as
"triggering the fault", in clear: fetching the objects
corresponding
to a to-many fault to turn the fault into a real list populated
w/ the
corresponding objects.

For example, need.getTasks() returns a fault, but calling len()
on it,
or accessing a member as in need.getTasks()[0], or inserting a
new
element in the list, triggers the fault and makes the framework
fetch
the objects=3D=3Dthe related tasks.

> >=20
> >     Respectively, check that (for 'need', same for 'team'
and
> >     'mealType'):
> >=20
> >     =20
db=3Dec.rootObjectStore().objectStoreForObject(task).database()
> >=20
> >       task_need_gID=3Dtask.getNeed().globalID()
> >       db.snapshotForGlobalID(task_need_gID=3Dtask) # None if
unfetched yet
> >=20
> >     and if it's not None:
> >=20
> >       db.snapshotForSourceGlobalID(task_need_gID, 'tasks')  #
should be ()
> >=20
> >     Otherwise you may experience weird side-effects on the
corresponding
> >     objects already fetched in other ECs, esp. when saving
them (no
> >     pb. if you use a single EC in the app., however).
>=20
> I'm not clear what the purpose of this is: is it to ensure that
the
> task.setMeal(None) is safe?

The purpose of the code I posted was to make sure that there
does
*not* exist an other EditingContext where the same object
task.getNeed() has been fetched and where the list
task.getNeed().getTasks() is not a fault anymore.

However I must now admit that the warning I wrote in my last post
was
in fact exagerated [1]: the only problem you can have is to
override
changes that have been made in an other EC --and the problem
we're
discussing here is just a particular point in a more general
category
of problems, the one exposed at
http://modeling.sf.net/UserGuide/framework-integration-sessioning-ec.html
and which has nothing to do in particular with relationships, but
w/
an object's properties in general.

    So you can forget that code, see below for a simpler one.

A related questions BTW:  are you using patch #911567 ?
https://sf.net/tracker/index.php?func=3Ddetail&aid=3D911567&group_id=3D58=
935&atid=3D489337
(which is a first step toward the resolution of the problem)

> basically what I'll be doing, unless you tell me otherwise,
is:
>=20
>   - for creating, do the task.setMeal(meal) but not the
meal.addToTasks(task)
>   - for deleteing, do the task.setMeal(None) but not the
> meal.removeFromTasks(task)
>=20
> given that I never, ever (promise! :D) clear the tasks, and
that I
> always saveChanges after deleteing or creating each task,
although I
> have many editingContexts (inside zope, one per session using
> ZEditingContextSessioning), it is my understanding that I'll be
safe.
> Right?

Okay, you can do this to *accelerate* the process of inserting,
and
removing tasks.  However, say, if a meal always have a
reasonable
number of related tasks, then the overhead of fetching those
meal's
tasks won't be noticeable, so in this case you'd better update
the two
sides of the relationships (same for Teams and Needs).  So the
answer
is: yes, do this w/ every kind of objects that *may* hold a real
bunch
of tasks (the kind(s) of objects that may be related to +20,000
tasks,
as seen in the previous posts).

And, if you do this: just make sure that

- either task.getMeal().isFault() =3D=3D true

- or that, in case it is not, that
    task.getMeal().getTasks().isFault()=3D=3Dtrue

  In this last case, if it is false, then you can do the=20
  meal.addToTasks(task) without any overhead, since this indicate
that
  the fetch has already be done.


Sorry again for having obfuscated the problem by my previous
answer,
hopefully this is clearer now.

-- S=E9bastien.


PS: my previous remarks about the possibility for the framework
to be
    smarter in the situation where the only modification is the
    addition or removal of objects from a list are still valid,
    though.


[1] I had in mind that the cache of to-many faults might become
    desynchronized wrt the database state, but since I checked
the
    code and the TODO list and realized that since cache is not
    used for now, no such problem can happen ;)



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=3D6595&alloc_id=3D14396&op=3Dclick