Skip to content
Snippets Groups Projects
Commit 3ca41bb0 authored by Michael Eischer's avatar Michael Eischer
Browse files

Send a request after a mode change only to the leader at first

Conflicting read request replies are not the leaders fault. So just
resend the request normally the first time.
parent e3e92427
No related branches found
No related tags found
No related merge requests found
......@@ -399,54 +399,9 @@ public class REFITLibByz extends REFITClientLibrary {
if (request.mode.isReadOnly() && (REFITConfig.USE_PBFT_READ_OPTIMIZATION || !request.mode.isTotalOrder())) {
boolean[] executionReplicas = REFITReplicaGroups.getExecutionReplicas(0);
if (!REFITConfig.SIGNED_REQUESTS) {
// Append MAC, special case for executors
request.setRecipientCount(REFITConfig.EXEC_GROUP_SIZE);
request.serializeMessage();
messageAuthentication.appendMulticastMAC(request, executionReplicas);
// Send directly to the execution replicas
sendToReplicas(request, executionReplicas);
} else {
// using MACs is sufficient as every executor processes the command on its own
// add MAC to wrapper to unify code paths
request.serializeMessage();
messageAuthentication.appendNullMAC(request);
for (short i = 0; i < executionReplicas.length; i++) {
if (!executionReplicas[i]) continue;
// wrap
REFITRequestWrapper wrapper = new REFITRequestWrapper(uid, getNodeID(), request);
wrapper.serializeMessage();
messageAuthentication.appendUnicastMAC(wrapper, i);
sendToReplica(wrapper, i);
}
}
multicastRequest(request, executionReplicas, REFITConfig.EXEC_GROUP_SIZE);
} else {
if (!REFITConfig.SIGNED_REQUESTS) {
// Append MAC
request.setRecipientCount(REFITConfig.ORDER_GROUP_SIZE);
request.serializeMessage();
messageAuthentication.appendMulticastMAC(request, REFITOrderGroups.getGroupByID(groupID));
if (!REFITConfig.USE_SPINNING_LEADER) {
// Send request to primary
sendToReplica(request, primaryID);
} else {
short[] group = REFITConfig.ORDER_GROUPS[request.groupID];
short replicaID = group[getNodeID() % group.length];
sendToReplica(request, replicaID);
}
} else {
request.serializeMessage();
// use signatures to prevent executors from damaging the request's authenticator
messageAuthentication.appendSignature(request);
// wrap
REFITRequestWrapper wrapper = new REFITRequestWrapper(uid, getNodeID(), request);
wrapper.serializeMessage();
messageAuthentication.appendUnicastMAC(wrapper, primaryID);
sendToReplica(wrapper, primaryID);
}
unicastRequestToPrimary(request);
}
} else if (request != null) {
if (request.mode.equals(RequestMode.PROBE)) {
......@@ -465,35 +420,74 @@ public class REFITLibByz extends REFITClientLibrary {
request = new REFITRequest(uid, getNodeID(), groupID, request.executeAfter, request.getPayload(), (short) -1, RequestMode.WRITE);
readWriteConflict = true;
// send first retry after mode change only to the primary
unicastRequestToPrimary(request);
} else {
request = new REFITRequest(request.uid, getNodeID(), groupID, request.executeAfter, request.getPayload(), (short) -1, request.mode);
request.markPanic();
}
if (!REFITConfig.SIGNED_REQUESTS) {
// Append MAC
request.setRecipientCount(retryGroupSize);
request.serializeMessage();
messageAuthentication.appendMulticastMAC(request, retryGroup);
sendToReplicas(request, retryGroup);
} else {
// use signatures to prevent executors from damaging the request's authenticator
request.serializeMessage();
messageAuthentication.appendSignature(request);
boolean[] replicas = REFITReplicaGroups.getExecutionReplicas(0);
for (short i = 0; i < replicas.length; i++) {
if (!replicas[i]) continue;
// wrap
REFITRequestWrapper wrapper = new REFITRequestWrapper(request.uid, getNodeID(), request);
wrapper.serializeMessage();
messageAuthentication.appendUnicastMAC(wrapper, i);
sendToReplica(wrapper, i);
if (!REFITConfig.SIGNED_REQUESTS) {
multicastRequest(request, retryGroup, retryGroupSize);
} else {
multicastRequest(request, REFITReplicaGroups.getExecutionReplicas(0), REFITConfig.EXEC_GROUP_SIZE);
}
}
}
progress();
}
private void unicastRequestToPrimary(REFITRequest request) {
if (!REFITConfig.SIGNED_REQUESTS) {
// Append MAC
request.setRecipientCount(REFITConfig.ORDER_GROUP_SIZE);
request.serializeMessage();
messageAuthentication.appendMulticastMAC(request, REFITOrderGroups.getGroupByID(request.groupID));
if (!REFITConfig.USE_SPINNING_LEADER) {
// Send request to primary
sendToReplica(request, primaryID);
} else {
short[] group = REFITConfig.ORDER_GROUPS[request.groupID];
short replicaID = group[getNodeID() % group.length];
sendToReplica(request, replicaID);
}
} else {
request.serializeMessage();
// use signatures to prevent executors from damaging the request's authenticator
messageAuthentication.appendSignature(request);
// wrap
REFITRequestWrapper wrapper = new REFITRequestWrapper(request.uid, getNodeID(), request);
wrapper.serializeMessage();
messageAuthentication.appendUnicastMAC(wrapper, primaryID);
sendToReplica(wrapper, primaryID);
}
}
private void multicastRequest(REFITRequest request, boolean[] executionReplicas, short recipientCount) {
if (!REFITConfig.SIGNED_REQUESTS) {
// Append MAC, special case for executors
request.setRecipientCount(recipientCount);
request.serializeMessage();
messageAuthentication.appendMulticastMAC(request, executionReplicas);
// Send directly to the execution replicas
sendToReplicas(request, executionReplicas);
} else {
// using MACs is sufficient as every executor processes the command on its own
// add MAC to wrapper to unify code paths
request.serializeMessage();
messageAuthentication.appendNullMAC(request);
for (short i = 0; i < executionReplicas.length; i++) {
if (!executionReplicas[i]) continue;
// wrap
REFITRequestWrapper wrapper = new REFITRequestWrapper(request.uid, getNodeID(), request);
wrapper.serializeMessage();
messageAuthentication.appendUnicastMAC(wrapper, i);
sendToReplica(wrapper, i);
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment