On Tue, 18 Jul 2006, Travis wrote:
Hi all,
I've found something which seems like a bug in the interaction between the
notification framework and stamping.
When new mail messages enter Chandler, I'd like to annotate them and put them
into a mail directory Item so they will be accessible to the IMAP server.
Currently, this works perfectly for all the entry cases I've tested (the IMAP
client, Item>New Item>Message, drag and drop from Thunderbird/Mail.app/etc)
except stamping. When a message is stamped, a repository commit during the
callback causes a very nasty error (which I've reproduced at the bottom of
this page).
A bit more exploration led to the creation of a parcel which illustrates this
bug. It appears that the problem is indeed caused by the commit during an
onCollectionNotification or watchKind callback. Removing the commit fixes the
problem, and the test parcel is sufficiently simple that it seems likely the
bug is coming from code already in Chandler's trunk.
Grant did some exploring and found the following:
So, here's what's seems to be going on:
The self.onCollectionNotification() callback that results from
notificationQueueSubscribe() is always happening in the main thread. When
you commit your changes (as you should), that causes a whole bunch of stuff
to happen, including changes to CPIA blocks in the app. That eventually
causes CPIA to get into a weird state; probably what's happening is the
commit in the middle of the refresh exposes some dependency on the order of
notification processing.
Doing a commit() inside a refresh() seems a little fishy and is sure to raise
some interesting questions about the sequence of things. At the end of
refresh(), a number of notifications are sent out, including the asynchronous
ones from the collection watch queue used by CPIA (and CPIA only).
Something that might work better, if you must trigger a commit() inside a
refresh(), is doing it asynchronously as well. Wait for refresh() to complete
and then commit(). One way to do this might be for me to delay any calls to
commit() inside refresh() until refresh() is done.
If you can simulate this by placing a call to commit() at the end of refresh()
in repository/persistence/DBRepositoryView.py and calling it when a condition
of yours is reached (use some global hack) and verify that it works, I can
then add support for that. What do you think ?
Andi..
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "chandler-dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/chandler-dev