{
UpdateMsg update = null;
while (update == null)
{
InitializeRequestMsg initReqMsg = null;
ReplicationMsg msg;
try
{
msg = broker.receive(true, true, false);
if (msg == null)
{
// The server is in the shutdown process
return null;
}
if (debugEnabled())
if (!(msg instanceof HeartbeatMsg))
TRACER.debugVerbose("Message received <" + msg + ">");
if (msg instanceof AckMsg)
{
AckMsg ack = (AckMsg) msg;
receiveAck(ack);
}
else if (msg instanceof InitializeRequestMsg)
{
// Another server requests us to provide entries
// for a total update
initReqMsg = (InitializeRequestMsg)msg;
}
else if (msg instanceof InitializeTargetMsg)
{
// Another server is exporting its entries to us
InitializeTargetMsg initTargetMsg = (InitializeTargetMsg) msg;
// This must be done while we are still holding the
// broker lock because we are now going to receive a
// bunch of entries from the remote server and we
// want the import thread to catch them and
// not the ListenerThread.
initialize(initTargetMsg, initTargetMsg.getSenderID());
}
else if (msg instanceof ErrorMsg)
{
ErrorMsg errorMsg = (ErrorMsg)msg;
if (ieContext != null)
{
// This is an error termination for the 2 following cases :
// - either during an export
// - or before an import really started
// For example, when we publish a request and the
// replicationServer did not find the import source.
//
// A remote error during the import will be received in the
// receiveEntryBytes() method.
//
if (debugEnabled())
TRACER.debugInfo(
"[IE] processErrorMsg:" + this.serverID +
" serviceID: " + this.serviceID +
" Error Msg received: " + errorMsg);
if (errorMsg.getCreationTime() > ieContext.startTime)
{
// consider only ErrorMsg that relate to the current import/export
processErrorMsg(errorMsg);
}
else
{
// Simply log - happen when the ErrorMsg relates to a previous
// attempt of initialization while we have started a new one
// on this side.
logError(ERR_ERROR_MSG_RECEIVED.get(errorMsg.getDetails()));
}
}
else
{
// Simply log - happen if import/export has been terminated
// on our side before receiving this ErrorMsg.
logError(ERR_ERROR_MSG_RECEIVED.get(errorMsg.getDetails()));
}
}
else if (msg instanceof ChangeStatusMsg)
{
ChangeStatusMsg csMsg = (ChangeStatusMsg)msg;
receiveChangeStatus(csMsg);
}
else if (msg instanceof UpdateMsg)
{
update = (UpdateMsg) msg;
generator.adjust(update.getChangeNumber());
}
else if (msg instanceof InitializeRcvAckMsg)
{
if (ieContext != null)
{
InitializeRcvAckMsg ackMsg = (InitializeRcvAckMsg) msg;
ieContext.setAckVal(ackMsg.getSenderID(), ackMsg.getNumAck());
}
// Trash this msg When no input/export is running/should never happen
}
}
catch (SocketTimeoutException e)
{
// just retry
}
// Test if we have received and export request message and
// if that's the case handle it now.
// This must be done outside of the portion of code protected
// by the broker lock so that we keep receiveing update
// when we are doing and export and so that a possible
// closure of the socket happening when we are publishing the
// entries to the remote can be handled by the other
// replay thread when they call this method and therefore the
// broker.receive() method.
if (initReqMsg != null)
{
// Do this work in a thread to allow replay thread continue working
ExportThread exportThread = new ExportThread(
initReqMsg.getSenderID(), initReqMsg.getInitWindow());
exportThread.start();
}
}
numRcvdUpdates.incrementAndGet();