Eric,
I appreciate your detailed analysis. I spent some time stepping through the
code and found that in COSynchronizerClient, it was doing the opposite of what
it seem it should when it receives a message with the same UUID as the last one
it sent. After removing the negation, the infinite loop is interrupted.
- (void) handleResponseMessage:
(COSynchronizerResponseToClientForSentRevisionsMessage *)aMessage
{
// if (![aMessage.lastRevisionUUIDSentByClient isEqual: [self
lastRevisionUUIDInTransitToServer]])
if ([aMessage.lastRevisionUUIDSentByClient isEqual: [self
lastRevisionUUIDInTransitToServer]])
{
return;
}
It seems possible that the infinite loop may only occur in a single-application
scenario such as this one, and why it does not happen in the sample app, a
single context in a thread will either sort itself out or keep spinning, but
will not get caught up in a sort of race condition where client/server are
trying to sort themselves out in the same thread.
I am also concerned with the following code at the end of
COSynchronizerServer::sendPushToClient
if (currentlyHandlingLastSentRevision != nil
&& [currentlyRespondingToClient isEqualToString: clientID])
{
ETAssert(currentlyRespondingToClient != nil);
COSynchronizerResponseToClientForSentRevisionsMessage * message
= [[COSynchronizerResponseToClientForSentRevisionsMessage alloc] init];
message.revisions = revs;
message.lastRevisionUUIDSentByClient =
currentlyHandlingLastSentRevision;
[self.delegate sendResponseMessage: message toClient: clientID];
currentlyHandlingLastSentRevision = nil;
currentlyRespondingToClient = nil;
}
else
{
COSynchronizerPushedRevisionsToClientMessage *message =
[[COSynchronizerPushedRevisionsToClientMessage alloc] init];
message.revisions = revs;
[self.delegate sendPushedRevisions: message toClients:
@[clientID]];
}
In my trace, the message that is created here is one with a single revision
(the one previously sent by the client), and the lastRevisionUUIDSentByClient
as being the same as the revision in the message. It seems like if this state
were to occur, it should not be sent to the client in the first place where it
is then handled in the code fixed handleResponseMessage.
I wonder if I am the first to attempt a synchronizer client/server within the
same thread. I will clean up and put this code up on GitHub for you to
examine, and perhaps contribute to the CoreObject samples at some point.
Thanks for your help._______________________________________________
Etoile-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-discuss