From 85d72efe96a86d2ac873484d5ec2e796fba268b0 Mon Sep 17 00:00:00 2001 From: Carmelo Cascone Date: Thu, 23 Aug 2018 19:06:29 -0700 Subject: [PATCH] Fix race to become master in P4Runtime before pipeline config set Change-Id: Id02e33a1d72d16ec49634ac57b6a4b56acdcf796 (cherry picked from commit 86f82c9e7ccd3912f77840e38eb7402a04f93681) --- .../p4runtime/ctl/P4RuntimeClientImpl.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java index a5c3c130bd..5483edc0c2 100644 --- a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java +++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java @@ -207,7 +207,7 @@ final class P4RuntimeClientImpl implements P4RuntimeClient { @Override public CompletableFuture start() { - return supplyInContext(this::doBecomeMaster, + return supplyInContext(() -> sendMasterArbitrationUpdate(false), "start-initStreamChannel"); } @@ -219,7 +219,7 @@ final class P4RuntimeClientImpl implements P4RuntimeClient { @Override public CompletableFuture becomeMaster() { - return supplyInContext(this::doBecomeMaster, + return supplyInContext(() -> sendMasterArbitrationUpdate(true), "becomeMaster"); } @@ -326,19 +326,20 @@ final class P4RuntimeClientImpl implements P4RuntimeClient { /* Blocking method implementations below */ - private boolean doBecomeMaster() { - final Uint128 newId = bigIntegerToUint128( - controller.newMasterElectionId(deviceId)); - if (sendMasterArbitrationUpdate(newId)) { - clientElectionId = newId; - return true; + private boolean sendMasterArbitrationUpdate(boolean asMaster) { + BigInteger newId = controller.newMasterElectionId(deviceId); + if (asMaster) { + // Becoming master is a race. Here we increase our chances of win + // against other ONOS nodes in the cluster that are calling start() + // (which is used to start the stream RPC session, not to become + // master). + newId = newId.add(BigInteger.valueOf(1000)); } - return false; - } + final Uint128 idMsg = bigIntegerToUint128( + controller.newMasterElectionId(deviceId)); - private boolean sendMasterArbitrationUpdate(Uint128 electionId) { log.info("Sending arbitration update to {}... electionId={}", - deviceId, uint128ToBigInteger(electionId)); + deviceId, newId); try { streamRequestObserver.onNext( StreamMessageRequest.newBuilder() @@ -346,9 +347,10 @@ final class P4RuntimeClientImpl implements P4RuntimeClient { MasterArbitrationUpdate .newBuilder() .setDeviceId(p4DeviceId) - .setElectionId(electionId) + .setElectionId(idMsg) .build()) .build()); + clientElectionId = idMsg; return true; } catch (StatusRuntimeException e) { log.error("Unable to perform arbitration update on {}: {}", deviceId, e.getMessage());