Committed by
Gerrit Code Review
Made intent perf app multi-threaded; doesn't seem to help.
Made Jono's changes to ECM per Madan's suggesion. Added cell beast. Re-enabled anti-entropy. Added ability to push bits through test proxy for faster upload. Change-Id: I1455d6d443a697d7a3973c88cb81bfdac0e1dd7f
Showing
9 changed files
with
215 additions
and
106 deletions
| ... | @@ -44,6 +44,7 @@ import org.onosproject.net.intent.PointToPointIntent; | ... | @@ -44,6 +44,7 @@ import org.onosproject.net.intent.PointToPointIntent; |
| 44 | import org.slf4j.Logger; | 44 | import org.slf4j.Logger; |
| 45 | 45 | ||
| 46 | import java.util.Collections; | 46 | import java.util.Collections; |
| 47 | +import java.util.HashSet; | ||
| 47 | import java.util.Iterator; | 48 | import java.util.Iterator; |
| 48 | import java.util.List; | 49 | import java.util.List; |
| 49 | import java.util.Map; | 50 | import java.util.Map; |
| ... | @@ -56,6 +57,7 @@ import java.util.concurrent.TimeUnit; | ... | @@ -56,6 +57,7 @@ import java.util.concurrent.TimeUnit; |
| 56 | 57 | ||
| 57 | import static com.google.common.base.Preconditions.checkState; | 58 | import static com.google.common.base.Preconditions.checkState; |
| 58 | import static java.lang.String.format; | 59 | import static java.lang.String.format; |
| 60 | +import static java.lang.System.currentTimeMillis; | ||
| 59 | import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY; | 61 | import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY; |
| 60 | import static org.onlab.util.Tools.delay; | 62 | import static org.onlab.util.Tools.delay; |
| 61 | import static org.onlab.util.Tools.groupedThreads; | 63 | import static org.onlab.util.Tools.groupedThreads; |
| ... | @@ -69,6 +71,13 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -69,6 +71,13 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 69 | @Component(immediate = true) | 71 | @Component(immediate = true) |
| 70 | public class IntentPerfInstaller { | 72 | public class IntentPerfInstaller { |
| 71 | 73 | ||
| 74 | + //FIXME make this configurable | ||
| 75 | + private static final int NUM_WORKERS = 1; | ||
| 76 | + private static final int NUM_KEYS = 10_000; | ||
| 77 | + | ||
| 78 | + public static final int START_DELAY = 5_000; // ms | ||
| 79 | + private static final int REPORT_PERIOD = 5_000; //ms | ||
| 80 | + | ||
| 72 | private final Logger log = getLogger(getClass()); | 81 | private final Logger log = getLogger(getClass()); |
| 73 | 82 | ||
| 74 | @Reference(cardinality = MANDATORY_UNARY) | 83 | @Reference(cardinality = MANDATORY_UNARY) |
| ... | @@ -83,32 +92,31 @@ public class IntentPerfInstaller { | ... | @@ -83,32 +92,31 @@ public class IntentPerfInstaller { |
| 83 | @Reference(cardinality = MANDATORY_UNARY) | 92 | @Reference(cardinality = MANDATORY_UNARY) |
| 84 | protected DeviceService deviceService; | 93 | protected DeviceService deviceService; |
| 85 | 94 | ||
| 86 | - private ExecutorService worker; | 95 | + private ExecutorService workers; |
| 87 | private ApplicationId appId; | 96 | private ApplicationId appId; |
| 88 | private Listener listener; | 97 | private Listener listener; |
| 89 | - private Set<Intent> intents; | ||
| 90 | - private Set<Intent> submitted; | ||
| 91 | - private Set<Intent> withdrawn; | ||
| 92 | private boolean stopped; | 98 | private boolean stopped; |
| 93 | 99 | ||
| 94 | - private static final long REPORT_PERIOD = 5000L; //ms | ||
| 95 | private Timer reportTimer; | 100 | private Timer reportTimer; |
| 96 | 101 | ||
| 97 | - //FIXME make this configurable | 102 | + private int lastKey = 0; |
| 98 | - private static final int NUM_KEYS = 10_000; | ||
| 99 | 103 | ||
| 100 | @Activate | 104 | @Activate |
| 101 | public void activate() { | 105 | public void activate() { |
| 102 | String nodeId = clusterService.getLocalNode().ip().toString(); | 106 | String nodeId = clusterService.getLocalNode().ip().toString(); |
| 103 | - appId = coreService.registerApplication("org.onosproject.intentperf." | 107 | + appId = coreService.registerApplication("org.onosproject.intentperf." + nodeId); |
| 104 | - + nodeId); | ||
| 105 | - intents = Sets.newHashSet(); | ||
| 106 | - submitted = Sets.newHashSet(); | ||
| 107 | - withdrawn = Sets.newHashSet(); | ||
| 108 | 108 | ||
| 109 | - worker = Executors.newFixedThreadPool(1, groupedThreads("onos/intent-perf", "worker")); | 109 | + reportTimer = new Timer("onos-intent-perf-reporter"); |
| 110 | + workers = Executors.newFixedThreadPool(NUM_WORKERS, groupedThreads("onos/intent-perf", "worker-%d")); | ||
| 110 | log.info("Started with Application ID {}", appId.id()); | 111 | log.info("Started with Application ID {}", appId.id()); |
| 111 | - start(); //FIXME | 112 | + |
| 113 | + // Schedule delayed start | ||
| 114 | + reportTimer.schedule(new TimerTask() { | ||
| 115 | + @Override | ||
| 116 | + public void run() { | ||
| 117 | + start(); | ||
| 118 | + } | ||
| 119 | + }, START_DELAY); | ||
| 112 | } | 120 | } |
| 113 | 121 | ||
| 114 | @Deactivate | 122 | @Deactivate |
| ... | @@ -123,26 +131,20 @@ public class IntentPerfInstaller { | ... | @@ -123,26 +131,20 @@ public class IntentPerfInstaller { |
| 123 | listener = new Listener(); | 131 | listener = new Listener(); |
| 124 | intentService.addListener(listener); | 132 | intentService.addListener(listener); |
| 125 | 133 | ||
| 126 | - long delay = System.currentTimeMillis() % REPORT_PERIOD; | 134 | + // Schedule reporter task on report period boundary |
| 127 | - reportTimer = new Timer("onos-intent-perf-reporter"); | ||
| 128 | reportTimer.scheduleAtFixedRate(new TimerTask() { | 135 | reportTimer.scheduleAtFixedRate(new TimerTask() { |
| 129 | @Override | 136 | @Override |
| 130 | public void run() { | 137 | public void run() { |
| 131 | listener.report(); | 138 | listener.report(); |
| 132 | } | 139 | } |
| 133 | - }, delay, REPORT_PERIOD); | 140 | + }, REPORT_PERIOD - currentTimeMillis() % REPORT_PERIOD, REPORT_PERIOD); |
| 134 | 141 | ||
| 142 | + // Submit workers | ||
| 135 | stopped = false; | 143 | stopped = false; |
| 136 | - worker.submit(() -> { | 144 | + Set<Device> devices = new HashSet<>(); |
| 137 | - delay(2000); // take a breath to start | 145 | + for (int i = 0; i < NUM_WORKERS; i++) { |
| 138 | - createIntents(NUM_KEYS, 2); //FIXME | 146 | + workers.submit(new Submitter(createIntents(NUM_KEYS, 2, lastKey, devices))); |
| 139 | - prime(); | 147 | + } |
| 140 | - while (!stopped) { | ||
| 141 | - cycle(); | ||
| 142 | - delay(800); // take a breath | ||
| 143 | - } | ||
| 144 | - }); | ||
| 145 | - | ||
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | public void stop() { | 150 | public void stop() { |
| ... | @@ -154,63 +156,53 @@ public class IntentPerfInstaller { | ... | @@ -154,63 +156,53 @@ public class IntentPerfInstaller { |
| 154 | } | 156 | } |
| 155 | stopped = true; | 157 | stopped = true; |
| 156 | try { | 158 | try { |
| 157 | - worker.awaitTermination(5, TimeUnit.SECONDS); | 159 | + workers.awaitTermination(5, TimeUnit.SECONDS); |
| 158 | } catch (InterruptedException e) { | 160 | } catch (InterruptedException e) { |
| 159 | log.warn("Failed to stop worker."); | 161 | log.warn("Failed to stop worker."); |
| 160 | } | 162 | } |
| 161 | } | 163 | } |
| 162 | 164 | ||
| 163 | - | ||
| 164 | - private void cycle() { | ||
| 165 | - long start = System.currentTimeMillis(); | ||
| 166 | - subset(submitted).forEach(this::withdraw); | ||
| 167 | - subset(withdrawn).forEach(this::submit); | ||
| 168 | - long delta = System.currentTimeMillis() - start; | ||
| 169 | - if (delta > 1000 || delta < 0) { | ||
| 170 | - log.warn("Cycle took {} ms", delta); | ||
| 171 | - } | ||
| 172 | - } | ||
| 173 | - | ||
| 174 | private Iterable<Intent> subset(Set<Intent> intents) { | 165 | private Iterable<Intent> subset(Set<Intent> intents) { |
| 175 | List<Intent> subset = Lists.newArrayList(intents); | 166 | List<Intent> subset = Lists.newArrayList(intents); |
| 176 | Collections.shuffle(subset); | 167 | Collections.shuffle(subset); |
| 177 | return subset.subList(0, subset.size() / 2); | 168 | return subset.subList(0, subset.size() / 2); |
| 178 | } | 169 | } |
| 179 | 170 | ||
| 180 | - private void submit(Intent intent) { | 171 | + /** |
| 181 | - intentService.submit(intent); | 172 | + * Creates a specified number of intents for testing purposes. |
| 182 | - submitted.add(intent); | 173 | + * |
| 183 | - withdrawn.remove(intent); //TODO could check result here... | 174 | + * @param numberOfKeys number of intents |
| 184 | - } | 175 | + * @param pathLength path depth |
| 185 | - | 176 | + * @param firstKey first key to attempt |
| 186 | - private void withdraw(Intent intent) { | 177 | + * @param devices set of previously utilized devices @return set of intents |
| 187 | - intentService.withdraw(intent); | 178 | + */ |
| 188 | - withdrawn.add(intent); | 179 | + private Set<Intent> createIntents(int numberOfKeys, int pathLength, |
| 189 | - submitted.remove(intent); //TODO could check result here... | 180 | + int firstKey, Set<Device> devices) { |
| 190 | - } | ||
| 191 | - | ||
| 192 | - private void createIntents(int numberOfKeys, int pathLength) { | ||
| 193 | Iterator<Device> deviceItr = deviceService.getAvailableDevices().iterator(); | 181 | Iterator<Device> deviceItr = deviceService.getAvailableDevices().iterator(); |
| 182 | + Set<Intent> result = new HashSet<>(); | ||
| 194 | 183 | ||
| 195 | Device ingressDevice = null; | 184 | Device ingressDevice = null; |
| 196 | while (deviceItr.hasNext()) { | 185 | while (deviceItr.hasNext()) { |
| 197 | Device device = deviceItr.next(); | 186 | Device device = deviceItr.next(); |
| 198 | - if (deviceService.getRole(device.id()) == MastershipRole.MASTER) { | 187 | + if (deviceService.getRole(device.id()) == MastershipRole.MASTER && |
| 188 | + !devices.contains(device)) { | ||
| 199 | ingressDevice = device; | 189 | ingressDevice = device; |
| 190 | + devices.add(device); | ||
| 200 | break; | 191 | break; |
| 201 | } | 192 | } |
| 202 | } | 193 | } |
| 203 | checkState(ingressDevice != null, "There are no local devices"); | 194 | checkState(ingressDevice != null, "There are no local devices"); |
| 204 | 195 | ||
| 205 | - for (int local = 0, i = 0; local < numberOfKeys; i++) { | 196 | + for (int count = 0, k = firstKey; count < numberOfKeys; k++) { |
| 206 | - Key key = Key.of(i, appId); | 197 | + Key key = Key.of(k, appId); |
| 207 | if (!intentService.isLocal(key)) { | 198 | if (!intentService.isLocal(key)) { |
| 199 | + // Bail if the key is not local | ||
| 208 | continue; | 200 | continue; |
| 209 | } | 201 | } |
| 210 | - TrafficSelector selector = DefaultTrafficSelector.builder().build(); | ||
| 211 | 202 | ||
| 212 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); | ||
| 213 | //FIXME | 203 | //FIXME |
| 204 | + TrafficSelector selector = DefaultTrafficSelector.builder().build(); | ||
| 205 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); | ||
| 214 | ConnectPoint ingress = new ConnectPoint(ingressDevice.id(), PortNumber.portNumber(1)); | 206 | ConnectPoint ingress = new ConnectPoint(ingressDevice.id(), PortNumber.portNumber(1)); |
| 215 | ConnectPoint egress = new ConnectPoint(ingressDevice.id(), PortNumber.portNumber(2)); | 207 | ConnectPoint egress = new ConnectPoint(ingressDevice.id(), PortNumber.portNumber(2)); |
| 216 | 208 | ||
| ... | @@ -218,28 +210,82 @@ public class IntentPerfInstaller { | ... | @@ -218,28 +210,82 @@ public class IntentPerfInstaller { |
| 218 | selector, treatment, | 210 | selector, treatment, |
| 219 | ingress, egress, | 211 | ingress, egress, |
| 220 | Collections.emptyList()); | 212 | Collections.emptyList()); |
| 221 | - intents.add(intent); | 213 | + result.add(intent); |
| 222 | - local++; | 214 | + |
| 223 | - if (i % 1000 == 0) { | 215 | + // Bump up the counter and remember this as the last key used. |
| 224 | - log.info("Building intents... {} ({})", local, i); | 216 | + count++; |
| 217 | + lastKey = k; | ||
| 218 | + if (lastKey % 1000 == 0) { | ||
| 219 | + log.info("Building intents... {} ({})", count, lastKey); | ||
| 225 | } | 220 | } |
| 226 | } | 221 | } |
| 227 | log.info("Created {} intents", numberOfKeys); | 222 | log.info("Created {} intents", numberOfKeys); |
| 223 | + return result; | ||
| 228 | } | 224 | } |
| 229 | 225 | ||
| 230 | - private void prime() { | 226 | + // Submits intent operations. |
| 231 | - int i = 0; | 227 | + final class Submitter implements Runnable { |
| 232 | - withdrawn.addAll(intents); | 228 | + |
| 233 | - for (Intent intent : intents) { | 229 | + private Set<Intent> intents = Sets.newHashSet(); |
| 234 | - submit(intent); | 230 | + private Set<Intent> submitted = Sets.newHashSet(); |
| 235 | - // only submit half of the intents to start | 231 | + private Set<Intent> withdrawn = Sets.newHashSet(); |
| 236 | - if (i++ >= intents.size() / 2) { | 232 | + |
| 237 | - break; | 233 | + private Submitter(Set<Intent> intents) { |
| 234 | + this.intents = intents; | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + @Override | ||
| 238 | + public void run() { | ||
| 239 | + delay(2000); // take a breath to start | ||
| 240 | + prime(); | ||
| 241 | + while (!stopped) { | ||
| 242 | + cycle(); | ||
| 243 | + delay(800); // take a breath | ||
| 244 | + } | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + // Submits the specified intent. | ||
| 248 | + private void submit(Intent intent) { | ||
| 249 | + intentService.submit(intent); | ||
| 250 | + submitted.add(intent); | ||
| 251 | + withdrawn.remove(intent); //TODO could check result here... | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + // Withdraws the specified intent. | ||
| 255 | + private void withdraw(Intent intent) { | ||
| 256 | + intentService.withdraw(intent); | ||
| 257 | + withdrawn.add(intent); | ||
| 258 | + submitted.remove(intent); //TODO could check result here... | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + // Primes the cycle. | ||
| 262 | + private void prime() { | ||
| 263 | + int i = 0; | ||
| 264 | + withdrawn.addAll(intents); | ||
| 265 | + for (Intent intent : intents) { | ||
| 266 | + submit(intent); | ||
| 267 | + // only submit half of the intents to start | ||
| 268 | + if (i++ >= intents.size() / 2) { | ||
| 269 | + break; | ||
| 270 | + } | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + // Runs a single operation cycle. | ||
| 275 | + private void cycle() { | ||
| 276 | + long start = currentTimeMillis(); | ||
| 277 | + subset(submitted).forEach(this::withdraw); | ||
| 278 | + subset(withdrawn).forEach(this::submit); | ||
| 279 | + long delta = currentTimeMillis() - start; | ||
| 280 | + if (delta > 5000 || delta < 0) { | ||
| 281 | + log.warn("Cycle took {} ms", delta); | ||
| 238 | } | 282 | } |
| 239 | } | 283 | } |
| 240 | } | 284 | } |
| 241 | 285 | ||
| 242 | - class Listener implements IntentListener { | 286 | + |
| 287 | + // Event listener to monitor throughput. | ||
| 288 | + final class Listener implements IntentListener { | ||
| 243 | 289 | ||
| 244 | private final Map<IntentEvent.Type, Counter> counters; | 290 | private final Map<IntentEvent.Type, Counter> counters; |
| 245 | private final Counter runningTotal = new Counter(); | 291 | private final Counter runningTotal = new Counter(); |
| ... | @@ -284,4 +330,5 @@ public class IntentPerfInstaller { | ... | @@ -284,4 +330,5 @@ public class IntentPerfInstaller { |
| 284 | return result; | 330 | return result; |
| 285 | } | 331 | } |
| 286 | } | 332 | } |
| 333 | + | ||
| 287 | } | 334 | } | ... | ... |
| ... | @@ -38,7 +38,7 @@ public class IntentAccumulator extends AbstractAccumulator<IntentData> { | ... | @@ -38,7 +38,7 @@ public class IntentAccumulator extends AbstractAccumulator<IntentData> { |
| 38 | 38 | ||
| 39 | // FIXME: Replace with a system-wide timer instance; | 39 | // FIXME: Replace with a system-wide timer instance; |
| 40 | // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt | 40 | // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt |
| 41 | - private static final Timer TIMER = new Timer("intent-op-batching"); | 41 | + private static final Timer TIMER = new Timer("onos-intent-op-batching"); |
| 42 | 42 | ||
| 43 | private final IntentBatchDelegate delegate; | 43 | private final IntentBatchDelegate delegate; |
| 44 | 44 | ... | ... |
| ... | @@ -65,14 +65,14 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -65,14 +65,14 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 65 | public class DefaultTopologyProvider extends AbstractProvider | 65 | public class DefaultTopologyProvider extends AbstractProvider |
| 66 | implements TopologyProvider { | 66 | implements TopologyProvider { |
| 67 | 67 | ||
| 68 | - private static final int MAX_THREADS = 32; | 68 | + private static final int MAX_THREADS = 8; |
| 69 | private static final int DEFAULT_MAX_EVENTS = 1000; | 69 | private static final int DEFAULT_MAX_EVENTS = 1000; |
| 70 | private static final int DEFAULT_MAX_IDLE_MS = 10; | 70 | private static final int DEFAULT_MAX_IDLE_MS = 10; |
| 71 | private static final int DEFAULT_MAX_BATCH_MS = 50; | 71 | private static final int DEFAULT_MAX_BATCH_MS = 50; |
| 72 | 72 | ||
| 73 | // FIXME: Replace with a system-wide timer instance; | 73 | // FIXME: Replace with a system-wide timer instance; |
| 74 | // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt | 74 | // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt |
| 75 | - private static final Timer TIMER = new Timer("topo-event-batching"); | 75 | + private static final Timer TIMER = new Timer("onos-topo-event-batching"); |
| 76 | 76 | ||
| 77 | @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS, | 77 | @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS, |
| 78 | label = "Maximum number of events to accumulate") | 78 | label = "Maximum number of events to accumulate") | ... | ... |
| ... | @@ -46,6 +46,7 @@ import java.util.concurrent.CopyOnWriteArraySet; | ... | @@ -46,6 +46,7 @@ import java.util.concurrent.CopyOnWriteArraySet; |
| 46 | import java.util.concurrent.ExecutorService; | 46 | import java.util.concurrent.ExecutorService; |
| 47 | import java.util.concurrent.Executors; | 47 | import java.util.concurrent.Executors; |
| 48 | import java.util.concurrent.ScheduledExecutorService; | 48 | import java.util.concurrent.ScheduledExecutorService; |
| 49 | +import java.util.concurrent.TimeUnit; | ||
| 49 | import java.util.stream.Collectors; | 50 | import java.util.stream.Collectors; |
| 50 | 51 | ||
| 51 | import static com.google.common.base.Preconditions.checkNotNull; | 52 | import static com.google.common.base.Preconditions.checkNotNull; |
| ... | @@ -66,7 +67,6 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -66,7 +67,6 @@ public class EventuallyConsistentMapImpl<K, V> |
| 66 | private final Map<K, Timestamped<V>> items; | 67 | private final Map<K, Timestamped<V>> items; |
| 67 | private final Map<K, Timestamp> removedItems; | 68 | private final Map<K, Timestamp> removedItems; |
| 68 | 69 | ||
| 69 | - private final String mapName; | ||
| 70 | private final ClusterService clusterService; | 70 | private final ClusterService clusterService; |
| 71 | private final ClusterCommunicationService clusterCommunicator; | 71 | private final ClusterCommunicationService clusterCommunicator; |
| 72 | private final KryoSerializer serializer; | 72 | private final KryoSerializer serializer; |
| ... | @@ -88,6 +88,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -88,6 +88,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 88 | 88 | ||
| 89 | private volatile boolean destroyed = false; | 89 | private volatile boolean destroyed = false; |
| 90 | private static final String ERROR_DESTROYED = " map is already destroyed"; | 90 | private static final String ERROR_DESTROYED = " map is already destroyed"; |
| 91 | + private final String destroyedMessage; | ||
| 91 | 92 | ||
| 92 | private static final String ERROR_NULL_KEY = "Key cannot be null"; | 93 | private static final String ERROR_NULL_KEY = "Key cannot be null"; |
| 93 | private static final String ERROR_NULL_VALUE = "Null values are not allowed"; | 94 | private static final String ERROR_NULL_VALUE = "Null values are not allowed"; |
| ... | @@ -98,18 +99,20 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -98,18 +99,20 @@ public class EventuallyConsistentMapImpl<K, V> |
| 98 | 99 | ||
| 99 | /** | 100 | /** |
| 100 | * Creates a new eventually consistent map shared amongst multiple instances. | 101 | * Creates a new eventually consistent map shared amongst multiple instances. |
| 101 | - * | 102 | + * <p> |
| 102 | * Each map is identified by a string map name. EventuallyConsistentMapImpl | 103 | * Each map is identified by a string map name. EventuallyConsistentMapImpl |
| 103 | * objects in different JVMs that use the same map name will form a | 104 | * objects in different JVMs that use the same map name will form a |
| 104 | * distributed map across JVMs (provided the cluster service is aware of | 105 | * distributed map across JVMs (provided the cluster service is aware of |
| 105 | * both nodes). | 106 | * both nodes). |
| 106 | - * | 107 | + * </p> |
| 108 | + * <p> | ||
| 107 | * The client is expected to provide an | 109 | * The client is expected to provide an |
| 108 | * {@link org.onlab.util.KryoNamespace.Builder} with which all classes that | 110 | * {@link org.onlab.util.KryoNamespace.Builder} with which all classes that |
| 109 | * will be stored in this map have been registered (including referenced | 111 | * will be stored in this map have been registered (including referenced |
| 110 | * classes). This serializer will be used to serialize both K and V for | 112 | * classes). This serializer will be used to serialize both K and V for |
| 111 | * inter-node notifications. | 113 | * inter-node notifications. |
| 112 | - * | 114 | + * </p> |
| 115 | + * <p> | ||
| 113 | * The client must provide an {@link org.onosproject.store.impl.ClockService} | 116 | * The client must provide an {@link org.onosproject.store.impl.ClockService} |
| 114 | * which can generate timestamps for a given key. The clock service is free | 117 | * which can generate timestamps for a given key. The clock service is free |
| 115 | * to generate timestamps however it wishes, however these timestamps will | 118 | * to generate timestamps however it wishes, however these timestamps will |
| ... | @@ -117,6 +120,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -117,6 +120,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 117 | * to ensure updates are properly ordered for the use case (i.e. in some | 120 | * to ensure updates are properly ordered for the use case (i.e. in some |
| 118 | * cases wallclock time will suffice, whereas in other cases logical time | 121 | * cases wallclock time will suffice, whereas in other cases logical time |
| 119 | * will be necessary). | 122 | * will be necessary). |
| 123 | + * </p> | ||
| 120 | * | 124 | * |
| 121 | * @param mapName a String identifier for the map. | 125 | * @param mapName a String identifier for the map. |
| 122 | * @param clusterService the cluster service | 126 | * @param clusterService the cluster service |
| ... | @@ -131,12 +135,11 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -131,12 +135,11 @@ public class EventuallyConsistentMapImpl<K, V> |
| 131 | ClusterCommunicationService clusterCommunicator, | 135 | ClusterCommunicationService clusterCommunicator, |
| 132 | KryoNamespace.Builder serializerBuilder, | 136 | KryoNamespace.Builder serializerBuilder, |
| 133 | ClockService<K, V> clockService) { | 137 | ClockService<K, V> clockService) { |
| 134 | - | ||
| 135 | - this.mapName = checkNotNull(mapName); | ||
| 136 | this.clusterService = checkNotNull(clusterService); | 138 | this.clusterService = checkNotNull(clusterService); |
| 137 | this.clusterCommunicator = checkNotNull(clusterCommunicator); | 139 | this.clusterCommunicator = checkNotNull(clusterCommunicator); |
| 138 | 140 | ||
| 139 | serializer = createSerializer(checkNotNull(serializerBuilder)); | 141 | serializer = createSerializer(checkNotNull(serializerBuilder)); |
| 142 | + destroyedMessage = mapName + ERROR_DESTROYED; | ||
| 140 | 143 | ||
| 141 | this.clockService = checkNotNull(clockService); | 144 | this.clockService = checkNotNull(clockService); |
| 142 | 145 | ||
| ... | @@ -153,10 +156,9 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -153,10 +156,9 @@ public class EventuallyConsistentMapImpl<K, V> |
| 153 | groupedThreads("onos/ecm", mapName + "-bg-%d"))); | 156 | groupedThreads("onos/ecm", mapName + "-bg-%d"))); |
| 154 | 157 | ||
| 155 | // start anti-entropy thread | 158 | // start anti-entropy thread |
| 156 | - //FIXME need to re-enable | 159 | + backgroundExecutor.scheduleAtFixedRate(new SendAdvertisementTask(), |
| 157 | -// backgroundExecutor.scheduleAtFixedRate(new SendAdvertisementTask(), | 160 | + initialDelaySec, periodSec, |
| 158 | -// initialDelaySec, periodSec, | 161 | + TimeUnit.SECONDS); |
| 159 | -// TimeUnit.SECONDS); | ||
| 160 | 162 | ||
| 161 | updateMessageSubject = new MessageSubject("ecm-" + mapName + "-update"); | 163 | updateMessageSubject = new MessageSubject("ecm-" + mapName + "-update"); |
| 162 | clusterCommunicator.addSubscriber(updateMessageSubject, | 164 | clusterCommunicator.addSubscriber(updateMessageSubject, |
| ... | @@ -191,6 +193,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -191,6 +193,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 191 | /** | 193 | /** |
| 192 | * Sets the executor to use for broadcasting messages and returns this | 194 | * Sets the executor to use for broadcasting messages and returns this |
| 193 | * instance for method chaining. | 195 | * instance for method chaining. |
| 196 | + * | ||
| 194 | * @param executor executor service | 197 | * @param executor executor service |
| 195 | * @return this instance | 198 | * @return this instance |
| 196 | */ | 199 | */ |
| ... | @@ -202,26 +205,26 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -202,26 +205,26 @@ public class EventuallyConsistentMapImpl<K, V> |
| 202 | 205 | ||
| 203 | @Override | 206 | @Override |
| 204 | public int size() { | 207 | public int size() { |
| 205 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 208 | + checkState(!destroyed, destroyedMessage); |
| 206 | return items.size(); | 209 | return items.size(); |
| 207 | } | 210 | } |
| 208 | 211 | ||
| 209 | @Override | 212 | @Override |
| 210 | public boolean isEmpty() { | 213 | public boolean isEmpty() { |
| 211 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 214 | + checkState(!destroyed, destroyedMessage); |
| 212 | return items.isEmpty(); | 215 | return items.isEmpty(); |
| 213 | } | 216 | } |
| 214 | 217 | ||
| 215 | @Override | 218 | @Override |
| 216 | public boolean containsKey(K key) { | 219 | public boolean containsKey(K key) { |
| 217 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 220 | + checkState(!destroyed, destroyedMessage); |
| 218 | checkNotNull(key, ERROR_NULL_KEY); | 221 | checkNotNull(key, ERROR_NULL_KEY); |
| 219 | return items.containsKey(key); | 222 | return items.containsKey(key); |
| 220 | } | 223 | } |
| 221 | 224 | ||
| 222 | @Override | 225 | @Override |
| 223 | public boolean containsValue(V value) { | 226 | public boolean containsValue(V value) { |
| 224 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 227 | + checkState(!destroyed, destroyedMessage); |
| 225 | checkNotNull(value, ERROR_NULL_VALUE); | 228 | checkNotNull(value, ERROR_NULL_VALUE); |
| 226 | 229 | ||
| 227 | return items.values().stream() | 230 | return items.values().stream() |
| ... | @@ -230,7 +233,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -230,7 +233,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 230 | 233 | ||
| 231 | @Override | 234 | @Override |
| 232 | public V get(K key) { | 235 | public V get(K key) { |
| 233 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 236 | + checkState(!destroyed, destroyedMessage); |
| 234 | checkNotNull(key, ERROR_NULL_KEY); | 237 | checkNotNull(key, ERROR_NULL_KEY); |
| 235 | 238 | ||
| 236 | Timestamped<V> value = items.get(key); | 239 | Timestamped<V> value = items.get(key); |
| ... | @@ -242,7 +245,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -242,7 +245,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 242 | 245 | ||
| 243 | @Override | 246 | @Override |
| 244 | public void put(K key, V value) { | 247 | public void put(K key, V value) { |
| 245 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 248 | + checkState(!destroyed, destroyedMessage); |
| 246 | checkNotNull(key, ERROR_NULL_KEY); | 249 | checkNotNull(key, ERROR_NULL_KEY); |
| 247 | checkNotNull(value, ERROR_NULL_VALUE); | 250 | checkNotNull(value, ERROR_NULL_VALUE); |
| 248 | 251 | ||
| ... | @@ -284,7 +287,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -284,7 +287,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 284 | 287 | ||
| 285 | @Override | 288 | @Override |
| 286 | public void remove(K key) { | 289 | public void remove(K key) { |
| 287 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 290 | + checkState(!destroyed, destroyedMessage); |
| 288 | checkNotNull(key, ERROR_NULL_KEY); | 291 | checkNotNull(key, ERROR_NULL_KEY); |
| 289 | 292 | ||
| 290 | // TODO prevent calls here if value is important for timestamp | 293 | // TODO prevent calls here if value is important for timestamp |
| ... | @@ -321,7 +324,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -321,7 +324,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 321 | 324 | ||
| 322 | @Override | 325 | @Override |
| 323 | public void remove(K key, V value) { | 326 | public void remove(K key, V value) { |
| 324 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 327 | + checkState(!destroyed, destroyedMessage); |
| 325 | checkNotNull(key, ERROR_NULL_KEY); | 328 | checkNotNull(key, ERROR_NULL_KEY); |
| 326 | checkNotNull(value, ERROR_NULL_VALUE); | 329 | checkNotNull(value, ERROR_NULL_VALUE); |
| 327 | 330 | ||
| ... | @@ -338,7 +341,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -338,7 +341,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 338 | 341 | ||
| 339 | @Override | 342 | @Override |
| 340 | public void putAll(Map<? extends K, ? extends V> m) { | 343 | public void putAll(Map<? extends K, ? extends V> m) { |
| 341 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 344 | + checkState(!destroyed, destroyedMessage); |
| 342 | 345 | ||
| 343 | List<PutEntry<K, V>> updates = new ArrayList<>(m.size()); | 346 | List<PutEntry<K, V>> updates = new ArrayList<>(m.size()); |
| 344 | 347 | ||
| ... | @@ -362,8 +365,8 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -362,8 +365,8 @@ public class EventuallyConsistentMapImpl<K, V> |
| 362 | for (PutEntry<K, V> entry : updates) { | 365 | for (PutEntry<K, V> entry : updates) { |
| 363 | EventuallyConsistentMapEvent<K, V> externalEvent = | 366 | EventuallyConsistentMapEvent<K, V> externalEvent = |
| 364 | new EventuallyConsistentMapEvent<>( | 367 | new EventuallyConsistentMapEvent<>( |
| 365 | - EventuallyConsistentMapEvent.Type.PUT, entry.key(), | 368 | + EventuallyConsistentMapEvent.Type.PUT, entry.key(), |
| 366 | - entry.value()); | 369 | + entry.value()); |
| 367 | notifyListeners(externalEvent); | 370 | notifyListeners(externalEvent); |
| 368 | } | 371 | } |
| 369 | } | 372 | } |
| ... | @@ -371,7 +374,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -371,7 +374,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 371 | 374 | ||
| 372 | @Override | 375 | @Override |
| 373 | public void clear() { | 376 | public void clear() { |
| 374 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 377 | + checkState(!destroyed, destroyedMessage); |
| 375 | 378 | ||
| 376 | List<RemoveEntry<K>> removed = new ArrayList<>(items.size()); | 379 | List<RemoveEntry<K>> removed = new ArrayList<>(items.size()); |
| 377 | 380 | ||
| ... | @@ -399,14 +402,14 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -399,14 +402,14 @@ public class EventuallyConsistentMapImpl<K, V> |
| 399 | 402 | ||
| 400 | @Override | 403 | @Override |
| 401 | public Set<K> keySet() { | 404 | public Set<K> keySet() { |
| 402 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 405 | + checkState(!destroyed, destroyedMessage); |
| 403 | 406 | ||
| 404 | return items.keySet(); | 407 | return items.keySet(); |
| 405 | } | 408 | } |
| 406 | 409 | ||
| 407 | @Override | 410 | @Override |
| 408 | public Collection<V> values() { | 411 | public Collection<V> values() { |
| 409 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 412 | + checkState(!destroyed, destroyedMessage); |
| 410 | 413 | ||
| 411 | return items.values().stream() | 414 | return items.values().stream() |
| 412 | .map(Timestamped::value) | 415 | .map(Timestamped::value) |
| ... | @@ -415,7 +418,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -415,7 +418,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 415 | 418 | ||
| 416 | @Override | 419 | @Override |
| 417 | public Set<Map.Entry<K, V>> entrySet() { | 420 | public Set<Map.Entry<K, V>> entrySet() { |
| 418 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 421 | + checkState(!destroyed, destroyedMessage); |
| 419 | 422 | ||
| 420 | return items.entrySet().stream() | 423 | return items.entrySet().stream() |
| 421 | .map(e -> Pair.of(e.getKey(), e.getValue().value())) | 424 | .map(e -> Pair.of(e.getKey(), e.getValue().value())) |
| ... | @@ -424,14 +427,14 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -424,14 +427,14 @@ public class EventuallyConsistentMapImpl<K, V> |
| 424 | 427 | ||
| 425 | @Override | 428 | @Override |
| 426 | public void addListener(EventuallyConsistentMapListener<K, V> listener) { | 429 | public void addListener(EventuallyConsistentMapListener<K, V> listener) { |
| 427 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 430 | + checkState(!destroyed, destroyedMessage); |
| 428 | 431 | ||
| 429 | listeners.add(checkNotNull(listener)); | 432 | listeners.add(checkNotNull(listener)); |
| 430 | } | 433 | } |
| 431 | 434 | ||
| 432 | @Override | 435 | @Override |
| 433 | public void removeListener(EventuallyConsistentMapListener<K, V> listener) { | 436 | public void removeListener(EventuallyConsistentMapListener<K, V> listener) { |
| 434 | - checkState(!destroyed, mapName + ERROR_DESTROYED); | 437 | + checkState(!destroyed, destroyedMessage); |
| 435 | 438 | ||
| 436 | listeners.remove(checkNotNull(listener)); | 439 | listeners.remove(checkNotNull(listener)); |
| 437 | } | 440 | } |
| ... | @@ -502,7 +505,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -502,7 +505,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 502 | Set<ControllerNode> nodes = clusterService.getNodes(); | 505 | Set<ControllerNode> nodes = clusterService.getNodes(); |
| 503 | 506 | ||
| 504 | List<NodeId> nodeIds = nodes.stream() | 507 | List<NodeId> nodeIds = nodes.stream() |
| 505 | - .map(node -> node.id()) | 508 | + .map(ControllerNode::id) |
| 506 | .collect(Collectors.toList()); | 509 | .collect(Collectors.toList()); |
| 507 | 510 | ||
| 508 | if (nodeIds.size() == 1 && nodeIds.get(0).equals(self)) { | 511 | if (nodeIds.size() == 1 && nodeIds.get(0).equals(self)) { |
| ... | @@ -689,7 +692,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -689,7 +692,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 689 | */ | 692 | */ |
| 690 | // Guarded by synchronized (this) | 693 | // Guarded by synchronized (this) |
| 691 | private List<EventuallyConsistentMapEvent<K, V>> | 694 | private List<EventuallyConsistentMapEvent<K, V>> |
| 692 | - antiEntropyCheckRemoteRemoved(AntiEntropyAdvertisement<K> ad) { | 695 | + antiEntropyCheckRemoteRemoved(AntiEntropyAdvertisement<K> ad) { |
| 693 | final List<EventuallyConsistentMapEvent<K, V>> externalEvents | 696 | final List<EventuallyConsistentMapEvent<K, V>> externalEvents |
| 694 | = new LinkedList<>(); | 697 | = new LinkedList<>(); |
| 695 | 698 | ||
| ... | @@ -752,8 +755,8 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -752,8 +755,8 @@ public class EventuallyConsistentMapImpl<K, V> |
| 752 | if (putInternal(key, value, timestamp)) { | 755 | if (putInternal(key, value, timestamp)) { |
| 753 | EventuallyConsistentMapEvent<K, V> externalEvent = | 756 | EventuallyConsistentMapEvent<K, V> externalEvent = |
| 754 | new EventuallyConsistentMapEvent<>( | 757 | new EventuallyConsistentMapEvent<>( |
| 755 | - EventuallyConsistentMapEvent.Type.PUT, key, | 758 | + EventuallyConsistentMapEvent.Type.PUT, key, |
| 756 | - value); | 759 | + value); |
| 757 | notifyListeners(externalEvent); | 760 | notifyListeners(externalEvent); |
| 758 | } | 761 | } |
| 759 | } | 762 | } | ... | ... |
| ... | @@ -4,7 +4,8 @@ | ... | @@ -4,7 +4,8 @@ |
| 4 | # ----------------------------------------------------------------------------- | 4 | # ----------------------------------------------------------------------------- |
| 5 | 5 | ||
| 6 | #export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/} | 6 | #export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/} |
| 7 | -export JAVA_OPTS="${JAVA_OPTS:--Xms256m -Xmx2g}" | 7 | +export JAVA_OPTS="${JAVA_OPTS:--Xms512m -Xmx2G}" |
| 8 | +# export JAVA_OPTS="${JAVA_OPTS:--Xms2G -Xmx8G}" # -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps}" | ||
| 8 | 9 | ||
| 9 | ONOS_HOME=/opt/onos | 10 | ONOS_HOME=/opt/onos |
| 10 | 11 | ... | ... |
tools/test/bin/onos-push-bits-through-proxy
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +# ----------------------------------------------------------------------------- | ||
| 3 | +# Remotely pushes bits to all remote nodes in preparation for install. | ||
| 4 | +# ----------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +node=${1:-$OCT} | ||
| 10 | +remote=$ONOS_USER@$node | ||
| 11 | +shift | ||
| 12 | + | ||
| 13 | +echo "Pushing to proxy $node..." | ||
| 14 | +onos-push-bits $node | ||
| 15 | + | ||
| 16 | +others=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) | ||
| 17 | + | ||
| 18 | +for other in $others; do | ||
| 19 | + echo "Pushing to $other..." | ||
| 20 | + ssh $remote "scp $ONOS_TAR $ONOS_USER@$other:$ONOS_TAR" | ||
| 21 | +done |
tools/test/cells/beast
0 → 100644
| 1 | +# Bare metal cluster | ||
| 2 | + | ||
| 3 | +# Use the 10G NIC for cluster communications | ||
| 4 | +export ONOS_NIC="192.168.200.*" | ||
| 5 | + | ||
| 6 | +# ONOS Test proxy | ||
| 7 | +export OCT=10.254.1.200 | ||
| 8 | + | ||
| 9 | +# Use the 1G NICs for external access | ||
| 10 | +export OC1=10.254.1.201 | ||
| 11 | +export OC2=10.254.1.202 | ||
| 12 | +export OC3=10.254.1.203 | ||
| 13 | +export OC4=10.254.1.204 | ||
| 14 | +export OC5=10.254.1.205 | ||
| 15 | +export OC6=10.254.1.206 | ||
| 16 | +export OC7=10.254.1.207 | ||
| 17 | + | ||
| 18 | +export OCI=${OC1} | ||
| 19 | + | ||
| 20 | +export ONOS_FEATURES=webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-null |
tools/test/cells/beast-3
0 → 100644
| 1 | +# Bare metal cluster | ||
| 2 | + | ||
| 3 | +# Use the 10G NIC for cluster communications | ||
| 4 | +export ONOS_NIC="192.168.200.*" | ||
| 5 | + | ||
| 6 | +# ONOS Test proxy | ||
| 7 | +export OCT=10.254.1.200 | ||
| 8 | + | ||
| 9 | +# Use the 1G NICs for external access | ||
| 10 | +export OC1=10.254.1.201 | ||
| 11 | +export OC2=10.254.1.202 | ||
| 12 | +export OC3=10.254.1.203 | ||
| 13 | + | ||
| 14 | +export OCI=${OC1} | ||
| 15 | + | ||
| 16 | +export ONOS_FEATURES=webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-null |
| ... | @@ -7,5 +7,6 @@ export OC3="10.128.11.3" | ... | @@ -7,5 +7,6 @@ export OC3="10.128.11.3" |
| 7 | export OCN="10.128.11.4" | 7 | export OCN="10.128.11.4" |
| 8 | 8 | ||
| 9 | export OCI="${OC1}" | 9 | export OCI="${OC1}" |
| 10 | +export OCT="${OC1}" | ||
| 10 | 11 | ||
| 11 | -export ONOS_FEATURES="webconsole,onos-api,onos-core,onos-cli,onos-openflow,onos-gui,onos-rest,onos-app-fwd,onos-app-proxyarp" | 12 | +export ONOS_FEATURES="webconsole,onos-api,onos-core,onos-cli,onos-rest,onos-null" | ... | ... |
-
Please register or login to post a comment