[Kde-pim] ChangeRecorder's pipeline

David Faure faure at kde.org
Sun Oct 14 02:11:10 BST 2012


Hi Volker,

88d868d9a52f1d0 introduced "d->pipeline.enqueue(msg)" in 
ChangeRecorder::replayNext() (which is still there in another form).

But the msg isn't removed from d->pendingNotifications (until the final call to 
changeProcessed), so if saveNotifications is called this message will be saved 
duplicated, won't it?

The handling of these two lists in the Monitor base class seems sane to me:
it's always pipeline = [A B C], pending = [D E] and stuff moves towards the 
left: A gets emitted when data is available, D moves in after C in 
dispatchNotification, and saving at that point would lead to [B C D E], all fine 
there.

But in ChangeRecorder the items get duplicated into the pipeline, and removed
from the pipeline when data is available, and later on removed from 
pendingNotifications when changeProcessed() is called. It took me 2 hours to 
find this :-}    (more details below)

It's almost fine to "abuse" the two lists that way, but I think 
saveNotifications() should then skip the pipeline when called from a 
ChangeRecorder, to avoid saving duplicates.
However, in addition, this makes things harder for any shared code that uses 
pipeline and pendingNotifications --- like what I plan to do, to speed up 
saving.
But I'm not sure if this can be done differently...
Maybe with a third list? Let's call it "emitted" and put it on the left:

emitted = [A], pipeline = [], pending = [B C D E]
where "emitted" is the one waiting for changeProcessed().
After that we get
emitted = [], pipeline = [B], pending = [C D E]
while waiting for dataAvailable in the Monitor base class, and before moving B 
to emitted.

In a pure Monitor emitted would always be empty, in ChangeRecorder it would 
have at most one message. Saving would save all three lists.

I think this would be easier to understand and manage than the current 
solution:
 pipeline = [], pending = [A B C D E]
which replayNext() turns into
 pipeline = [A], pending = [A B C D E]
and which MonitorPrivate::flushPipeline() turns back into
 pipeline = [], pending = [A B C D E]
again before emitNotification() and while waiting for changeProcessed(), which 
finally removes A from pending. Tricky, isn't it? :-)

My first try was to just remove A from the pending list in replayNext(), but 
this would lose data if the process crashes after the data is available 
(emitNotification) and before changeProcessed().

Please correct me if any of this analysis is wrong, and please voice any 
better suggestion you might have for both
1) not saving duplicates
2) using these lists in a consistent way between both classes, in order to be 
able to add more logic in the saving code.

-- 
David Faure, faure at kde.org, http://www.davidfaure.fr
Working on KDE, in particular KDE Frameworks 5

_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/



More information about the kde-pim mailing list