/**
* Immediately return the ack for an assured message in safe data
* mode with safe data level 1, coming from a DS. No need to wait
* for more acks
*/
AckMsg ack = new AckMsg(cn);
sourceHandler.sendAck(ack);
} else
{
if (safeDataLevel != (byte) 0)
{
/**
* level > 1 : We need further acks
* The message will be posted in assured mode to eligible
* servers. The embedded safe data level is not changed, and his
* value will be used by a remote RS to determine if he must send
* an ack (level > 1) or not (level = 1)
*/
interestedInAcks = true;
} else
{
// Should never happen
}
}
} else
{ // A RS sent us the safe data message, for sure no further ack to wait
if (safeDataLevel == (byte) 1)
{
/**
* The original level was 1 so the RS that sent us this message
* should have already sent his ack to the sender DS. Level 1 has
* already been reached so no further acks to wait.
* This should not happen in theory as the sender RS server should
* have sent us a matching not assured message so we should not come
* to here.
*/
} else
{
// level > 1, so Ack this message to originator RS
AckMsg ack = new AckMsg(cn);
sourceHandler.sendAck(ack);
}
}
}
}
List<Integer> expectedServers = new ArrayList<Integer>();
if (interestedInAcks)
{
if (sourceHandler.isDataServer())
{
// Look for RS eligible for assured
for (ReplicationServerHandler handler : replicationServers.values())
{
if (handler.getGroupId() == groupId)
// No ack expected from a RS with different group id
{
if ((generationId > 0) &&
(generationId == handler.getGenerationId()))
// No ack expected from a RS with bad gen id
{
expectedServers.add(handler.getServerId());
}
}
}
}
}
// Return computed structures
PreparedAssuredInfo preparedAssuredInfo = new PreparedAssuredInfo();
int nExpectedServers = expectedServers.size();
if (interestedInAcks) // interestedInAcks so level > 1
{
if (nExpectedServers > 0)
{
// Some other acks to wait for
int sdl = update.getSafeDataLevel();
int neededAdditionalServers = sdl - 1;
// Change the number of expected acks if not enough available eligible
// servers: the level is a best effort thing, we do not want to timeout
// at every assured SD update for instance if a RS has had his gen id
// reseted
byte finalSdl = ((nExpectedServers >= neededAdditionalServers) ?
(byte)sdl : // Keep level as it was
(byte)(nExpectedServers+1)); // Change level to match what's available
preparedAssuredInfo.expectedAcksInfo = new SafeDataExpectedAcksInfo(cn,
sourceHandler, finalSdl, expectedServers);
preparedAssuredInfo.expectedServers = expectedServers;
} else
{
// level > 1 and source is a DS but no eligible servers found, send the
// ack immediately
AckMsg ack = new AckMsg(cn);
sourceHandler.sendAck(ack);
}
}
return preparedAssuredInfo;