On Wed, 2013-06-26 at 16:10 +0200, Patrick Ohly wrote: > On Mon, 2013-06-10 at 12:35 +0200, Lukas Zeller wrote: > > On 10.06.2013, at 11:57, Patrick Ohly <[email protected]> wrote: > > > I'll probably try something else: if commands were delayed in a > > > message which is marked Final, then force execution of the commands at > > > the end of processing that message and issue their Status commands, just > > > as syncing normally would. > > > > Sounds like a good compromise to me. > > I've implemented that. I've run this through a full test against > different peers, without problems. Or rather, there were problems > earlier, which shows that the tests covered relevant corner cases ;-) > These problems have been addressed.
After adding more tests, I found one more problem: the combination of <Moredata> and queuing preceding items failed. Patch attached. I intend to squash it into the "preserve status order" patch before including FDO master branch. -- Best Regards, Patrick Ohly The content of this message is my personal opinion only and although I am an employee of Intel, the statements I make here in no way represent Intel's position on the issue, nor am I authorized to speak on behalf of Intel on this matter.
>From 1f01b69ee1aa597924f90c48a299db254a0cd5d9 Mon Sep 17 00:00:00 2001 From: Patrick Ohly <[email protected]> Date: Mon, 1 Jul 2013 08:52:47 +0200 Subject: [PATCH 1/4] merge: ordered status Add/Replace commands which contain incomplete items are special: they must trigger a Status 213 response in the same message, which cannot be done without processing the previously queued commands first. We could try to queue the incomplete command without processing it at all, but that would change the response in a way that might be unexpected by the peer (although legal). Better play it safe and finish all queued commands, then process the command. --- src/sysync/synccommand.cpp | 18 ++++++++++++++++++ src/sysync/synccommand.h | 4 ++++ src/sysync/syncsession.cpp | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/src/sysync/synccommand.cpp b/src/sysync/synccommand.cpp index ef363d1..3b27d63 100755 --- a/src/sysync/synccommand.cpp +++ b/src/sysync/synccommand.cpp @@ -2289,6 +2289,24 @@ missingeoc: } // TSyncOpCommand::AddNextChunk +// SyncOp commands can execute out of order except when they +// contain chunked items, because then we would have to issue +// a 213 Status immediately, which would violate the ordering +// of Status replies. +bool TSyncOpCommand::canExecuteOutOfOrder() +{ + SmlItemListPtr_t *itemnodePP=&(fSyncOpElementP->itemList); + while (*itemnodePP) { + SmlItemListPtr_t thisitemnode = *itemnodePP; + if (thisitemnode->item && + thisitemnode->item->flags & SmlMoreData_f) { + return false; + } + itemnodePP = &(thisitemnode->next); + } + return true; +} + // execute command (perform real actions, generate status) // returns true if command has executed and can be deleted bool TSyncOpCommand::execute(void) diff --git a/src/sysync/synccommand.h b/src/sysync/synccommand.h index bc5869c..c070905 100755 --- a/src/sysync/synccommand.h +++ b/src/sysync/synccommand.h @@ -90,6 +90,9 @@ public: #endif // - analyze command (but do not yet execute) virtual bool analyze(TPackageStates aPackageState) { fPackageState=aPackageState; return true; }; // returns false if command is bad and cannot be executed + // - execute() can be called even if there are other already queued commands. + // True by default, exceptions must be defined explicitly. + virtual bool canExecuteOutOfOrder() { return true; } // - execute command (perform real actions, generate status) virtual bool execute(void); // returns true if command could execute, false if it must be queued for later finishing (next message) // - get number of bytes that will be still available in the workspace after @@ -413,6 +416,7 @@ public: virtual ~TSyncOpCommand(); virtual bool isSyncOp() { return true; }; virtual bool analyze(TPackageStates aPackageState); + virtual bool canExecuteOutOfOrder(); virtual bool execute(void); #ifndef USE_SML_EVALUATION // - get (approximated) message size required for sending it diff --git a/src/sysync/syncsession.cpp b/src/sysync/syncsession.cpp index 870342a..a394bed 100644 --- a/src/sysync/syncsession.cpp +++ b/src/sysync/syncsession.cpp @@ -2549,6 +2549,13 @@ Ret_t TSyncSession::process(TSmlCommand *aSyncCommandP) delayExecUntilNextRequest(aSyncCommandP); } else { + if (fDelayedExecutionCommands.size()>0 && + !aSyncCommandP->canExecuteOutOfOrder()) { + PDEBUGPRINTFX(DBG_SESSION,("%s: command cannot be executed with other commands already delayed -> flush queue",aSyncCommandP->getName())); + fCmdIncoming = NULL; + tryDelayedExecutionCommands(); + } + // command is ok, execute it fCmdIncomingState=aSyncCommandP->getPackageState(); // Queue Status commands issued during execute()? -- 1.7.10.4
_______________________________________________ os-libsynthesis mailing list [email protected] http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
