Committed by
Gerrit Code Review
ONOS-2315 Adding new metrics to ConsistentMaps
Change-Id: Iba9a70f5eb268834564be26e42776b9caa4ea547
Showing
1 changed file
with
147 additions
and
30 deletions
... | @@ -25,6 +25,7 @@ import java.util.Map.Entry; | ... | @@ -25,6 +25,7 @@ import java.util.Map.Entry; |
25 | import java.util.Objects; | 25 | import java.util.Objects; |
26 | import java.util.concurrent.CompletableFuture; | 26 | import java.util.concurrent.CompletableFuture; |
27 | import java.util.concurrent.CopyOnWriteArraySet; | 27 | import java.util.concurrent.CopyOnWriteArraySet; |
28 | +import java.util.concurrent.TimeUnit; | ||
28 | import java.util.concurrent.atomic.AtomicReference; | 29 | import java.util.concurrent.atomic.AtomicReference; |
29 | import java.util.function.BiFunction; | 30 | import java.util.function.BiFunction; |
30 | import java.util.function.Consumer; | 31 | import java.util.function.Consumer; |
... | @@ -33,6 +34,11 @@ import java.util.function.Predicate; | ... | @@ -33,6 +34,11 @@ import java.util.function.Predicate; |
33 | import java.util.stream.Collectors; | 34 | import java.util.stream.Collectors; |
34 | import java.util.Set; | 35 | import java.util.Set; |
35 | 36 | ||
37 | +import com.codahale.metrics.Timer; | ||
38 | +import org.onlab.metrics.MetricsComponent; | ||
39 | +import org.onlab.metrics.MetricsFeature; | ||
40 | +import org.onlab.metrics.MetricsService; | ||
41 | +import org.onlab.osgi.DefaultServiceDirectory; | ||
36 | import org.onlab.util.HexString; | 42 | import org.onlab.util.HexString; |
37 | import org.onlab.util.SharedExecutors; | 43 | import org.onlab.util.SharedExecutors; |
38 | import org.onlab.util.Tools; | 44 | import org.onlab.util.Tools; |
... | @@ -70,6 +76,34 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -70,6 +76,34 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
70 | private final boolean purgeOnUninstall; | 76 | private final boolean purgeOnUninstall; |
71 | private final Consumer<MapEvent<K, V>> eventPublisher; | 77 | private final Consumer<MapEvent<K, V>> eventPublisher; |
72 | 78 | ||
79 | + private final MetricsService metricsService; | ||
80 | + private final MetricsComponent metricsComponent; | ||
81 | + private final MetricsFeature metricsFeature; | ||
82 | + private final Map<String, Timer> perMapOpTimers = Maps.newConcurrentMap(); | ||
83 | + private final Map<String, Timer> perOpTimers = Maps.newConcurrentMap(); | ||
84 | + private final Timer cMapTimer; | ||
85 | + private final Timer perMapTimer; | ||
86 | + private final MetricsFeature wildcard; | ||
87 | + | ||
88 | + private static final String COMPONENT_NAME = "consistentMap"; | ||
89 | + private static final String SIZE = "size"; | ||
90 | + private static final String IS_EMPTY = "isEmpty"; | ||
91 | + private static final String CONTAINS_KEY = "containsKey"; | ||
92 | + private static final String CONTAINS_VALUE = "containsValue"; | ||
93 | + private static final String GET = "get"; | ||
94 | + private static final String COMPUTE_IF = "computeIf"; | ||
95 | + private static final String PUT = "put"; | ||
96 | + private static final String PUT_AND_GET = "putAndGet"; | ||
97 | + private static final String PUT_IF_ABSENT = "putIfAbsent"; | ||
98 | + private static final String REMOVE = "remove"; | ||
99 | + private static final String CLEAR = "clear"; | ||
100 | + private static final String KEY_SET = "keySet"; | ||
101 | + private static final String VALUES = "values"; | ||
102 | + private static final String ENTRY_SET = "entrySet"; | ||
103 | + private static final String REPLACE = "replace"; | ||
104 | + private static final String COMPUTE_IF_ABSENT = "computeIfAbsent"; | ||
105 | + | ||
106 | + | ||
73 | private final Set<MapEventListener<K, V>> listeners = new CopyOnWriteArraySet<>(); | 107 | private final Set<MapEventListener<K, V>> listeners = new CopyOnWriteArraySet<>(); |
74 | 108 | ||
75 | private final Logger log = getLogger(getClass()); | 109 | private final Logger log = getLogger(getClass()); |
... | @@ -116,6 +150,13 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -116,6 +150,13 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
116 | } | 150 | } |
117 | }); | 151 | }); |
118 | }); | 152 | }); |
153 | + this.metricsService = DefaultServiceDirectory.getService(MetricsService.class); | ||
154 | + this.metricsComponent = metricsService.registerComponent(COMPONENT_NAME); | ||
155 | + this.metricsFeature = metricsComponent.registerFeature(name); | ||
156 | + this.wildcard = metricsComponent.registerFeature("*"); | ||
157 | + this.perMapTimer = metricsService.createTimer(metricsComponent, metricsFeature, "*"); | ||
158 | + this.cMapTimer = metricsService.createTimer(metricsComponent, wildcard, "*"); | ||
159 | + | ||
119 | } | 160 | } |
120 | 161 | ||
121 | /** | 162 | /** |
... | @@ -153,31 +194,41 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -153,31 +194,41 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
153 | 194 | ||
154 | @Override | 195 | @Override |
155 | public CompletableFuture<Integer> size() { | 196 | public CompletableFuture<Integer> size() { |
156 | - return database.mapSize(name); | 197 | + final OperationTimer timer = startTimer(SIZE); |
198 | + return database.mapSize(name) | ||
199 | + .whenComplete((r, e) -> timer.stop()); | ||
157 | } | 200 | } |
158 | 201 | ||
159 | @Override | 202 | @Override |
160 | public CompletableFuture<Boolean> isEmpty() { | 203 | public CompletableFuture<Boolean> isEmpty() { |
161 | - return database.mapIsEmpty(name); | 204 | + final OperationTimer timer = startTimer(IS_EMPTY); |
205 | + return database.mapIsEmpty(name) | ||
206 | + .whenComplete((r, e) -> timer.stop()); | ||
162 | } | 207 | } |
163 | 208 | ||
164 | @Override | 209 | @Override |
165 | public CompletableFuture<Boolean> containsKey(K key) { | 210 | public CompletableFuture<Boolean> containsKey(K key) { |
166 | checkNotNull(key, ERROR_NULL_KEY); | 211 | checkNotNull(key, ERROR_NULL_KEY); |
167 | - return database.mapContainsKey(name, keyCache.getUnchecked(key)); | 212 | + final OperationTimer timer = startTimer(CONTAINS_KEY); |
213 | + return database.mapContainsKey(name, keyCache.getUnchecked(key)) | ||
214 | + .whenComplete((r, e) -> timer.stop()); | ||
168 | } | 215 | } |
169 | 216 | ||
170 | @Override | 217 | @Override |
171 | public CompletableFuture<Boolean> containsValue(V value) { | 218 | public CompletableFuture<Boolean> containsValue(V value) { |
172 | checkNotNull(value, ERROR_NULL_VALUE); | 219 | checkNotNull(value, ERROR_NULL_VALUE); |
173 | - return database.mapContainsValue(name, serializer.encode(value)); | 220 | + final OperationTimer timer = startTimer(CONTAINS_VALUE); |
221 | + return database.mapContainsValue(name, serializer.encode(value)) | ||
222 | + .whenComplete((r, e) -> timer.stop()); | ||
174 | } | 223 | } |
175 | 224 | ||
176 | @Override | 225 | @Override |
177 | public CompletableFuture<Versioned<V>> get(K key) { | 226 | public CompletableFuture<Versioned<V>> get(K key) { |
178 | checkNotNull(key, ERROR_NULL_KEY); | 227 | checkNotNull(key, ERROR_NULL_KEY); |
228 | + final OperationTimer timer = startTimer(GET); | ||
179 | return database.mapGet(name, keyCache.getUnchecked(key)) | 229 | return database.mapGet(name, keyCache.getUnchecked(key)) |
180 | - .thenApply(v -> v != null ? v.map(serializer::decode) : null); | 230 | + .whenComplete((r, e) -> timer.stop()) |
231 | + .thenApply(v -> v != null ? v.map(serializer::decode) : null); | ||
181 | } | 232 | } |
182 | 233 | ||
183 | @Override | 234 | @Override |
... | @@ -185,7 +236,10 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -185,7 +236,10 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
185 | Function<? super K, ? extends V> mappingFunction) { | 236 | Function<? super K, ? extends V> mappingFunction) { |
186 | checkNotNull(key, ERROR_NULL_KEY); | 237 | checkNotNull(key, ERROR_NULL_KEY); |
187 | checkNotNull(mappingFunction, "Mapping function cannot be null"); | 238 | checkNotNull(mappingFunction, "Mapping function cannot be null"); |
188 | - return updateAndGet(key, Match.ifNull(), Match.any(), mappingFunction.apply(key)).thenApply(v -> v.newValue()); | 239 | + final OperationTimer timer = startTimer(COMPUTE_IF_ABSENT); |
240 | + return updateAndGet(key, Match.ifNull(), Match.any(), mappingFunction.apply(key)) | ||
241 | + .whenComplete((r, e) -> timer.stop()) | ||
242 | + .thenApply(v -> v.newValue()); | ||
189 | } | 243 | } |
190 | 244 | ||
191 | @Override | 245 | @Override |
... | @@ -207,6 +261,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -207,6 +261,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
207 | checkNotNull(key, ERROR_NULL_KEY); | 261 | checkNotNull(key, ERROR_NULL_KEY); |
208 | checkNotNull(condition, "predicate function cannot be null"); | 262 | checkNotNull(condition, "predicate function cannot be null"); |
209 | checkNotNull(remappingFunction, "Remapping function cannot be null"); | 263 | checkNotNull(remappingFunction, "Remapping function cannot be null"); |
264 | + final OperationTimer timer = startTimer(COMPUTE_IF); | ||
210 | return get(key).thenCompose(r1 -> { | 265 | return get(key).thenCompose(r1 -> { |
211 | V existingValue = r1 == null ? null : r1.value(); | 266 | V existingValue = r1 == null ? null : r1.value(); |
212 | // if the condition evaluates to false, return existing value. | 267 | // if the condition evaluates to false, return existing value. |
... | @@ -227,6 +282,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -227,6 +282,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
227 | Match<V> valueMatcher = r1 == null ? Match.ifNull() : Match.any(); | 282 | Match<V> valueMatcher = r1 == null ? Match.ifNull() : Match.any(); |
228 | Match<Long> versionMatcher = r1 == null ? Match.any() : Match.ifValue(r1.version()); | 283 | Match<Long> versionMatcher = r1 == null ? Match.any() : Match.ifValue(r1.version()); |
229 | return updateAndGet(key, valueMatcher, versionMatcher, computedValue.get()) | 284 | return updateAndGet(key, valueMatcher, versionMatcher, computedValue.get()) |
285 | + .whenComplete((r, e) -> timer.stop()) | ||
230 | .thenApply(v -> { | 286 | .thenApply(v -> { |
231 | if (v.updated()) { | 287 | if (v.updated()) { |
232 | return v.newValue(); | 288 | return v.newValue(); |
... | @@ -241,71 +297,96 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -241,71 +297,96 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
241 | public CompletableFuture<Versioned<V>> put(K key, V value) { | 297 | public CompletableFuture<Versioned<V>> put(K key, V value) { |
242 | checkNotNull(key, ERROR_NULL_KEY); | 298 | checkNotNull(key, ERROR_NULL_KEY); |
243 | checkNotNull(value, ERROR_NULL_VALUE); | 299 | checkNotNull(value, ERROR_NULL_VALUE); |
244 | - return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.oldValue()); | 300 | + final OperationTimer timer = startTimer(PUT); |
301 | + return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.oldValue()) | ||
302 | + .whenComplete((r, e) -> timer.stop()); | ||
245 | } | 303 | } |
246 | 304 | ||
247 | @Override | 305 | @Override |
248 | public CompletableFuture<Versioned<V>> putAndGet(K key, V value) { | 306 | public CompletableFuture<Versioned<V>> putAndGet(K key, V value) { |
249 | checkNotNull(key, ERROR_NULL_KEY); | 307 | checkNotNull(key, ERROR_NULL_KEY); |
250 | checkNotNull(value, ERROR_NULL_VALUE); | 308 | checkNotNull(value, ERROR_NULL_VALUE); |
251 | - return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.newValue()); | 309 | + final OperationTimer timer = startTimer(PUT_AND_GET); |
310 | + return updateAndGet(key, Match.any(), Match.any(), value).thenApply(v -> v.newValue()) | ||
311 | + .whenComplete((r, e) -> timer.stop()); | ||
252 | } | 312 | } |
253 | 313 | ||
254 | @Override | 314 | @Override |
255 | public CompletableFuture<Versioned<V>> remove(K key) { | 315 | public CompletableFuture<Versioned<V>> remove(K key) { |
256 | checkNotNull(key, ERROR_NULL_KEY); | 316 | checkNotNull(key, ERROR_NULL_KEY); |
257 | - return updateAndGet(key, Match.any(), Match.any(), null).thenApply(v -> v.oldValue()); | 317 | + final OperationTimer timer = startTimer(REMOVE); |
318 | + return updateAndGet(key, Match.any(), Match.any(), null).thenApply(v -> v.oldValue()) | ||
319 | + .whenComplete((r, e) -> timer.stop()); | ||
258 | } | 320 | } |
259 | 321 | ||
260 | @Override | 322 | @Override |
261 | public CompletableFuture<Void> clear() { | 323 | public CompletableFuture<Void> clear() { |
262 | checkIfUnmodifiable(); | 324 | checkIfUnmodifiable(); |
263 | - return database.mapClear(name).thenApply(this::unwrapResult); | 325 | + final OperationTimer timer = startTimer(CLEAR); |
326 | + return database.mapClear(name).thenApply(this::unwrapResult) | ||
327 | + .whenComplete((r, e) -> timer.stop()); | ||
264 | } | 328 | } |
265 | 329 | ||
266 | @Override | 330 | @Override |
267 | public CompletableFuture<Set<K>> keySet() { | 331 | public CompletableFuture<Set<K>> keySet() { |
332 | + final OperationTimer timer = startTimer(KEY_SET); | ||
268 | return database.mapKeySet(name) | 333 | return database.mapKeySet(name) |
269 | .thenApply(s -> s | 334 | .thenApply(s -> s |
270 | - .stream() | 335 | + .stream() |
271 | - .map(this::dK) | 336 | + .map(this::dK) |
272 | - .collect(Collectors.toSet())); | 337 | + .collect(Collectors.toSet())) |
338 | + .whenComplete((r, e) -> timer.stop()); | ||
273 | } | 339 | } |
274 | 340 | ||
275 | @Override | 341 | @Override |
276 | public CompletableFuture<Collection<Versioned<V>>> values() { | 342 | public CompletableFuture<Collection<Versioned<V>>> values() { |
277 | - return database.mapValues(name).thenApply(c -> c | 343 | + final OperationTimer timer = startTimer(VALUES); |
278 | - .stream() | 344 | + return database.mapValues(name) |
279 | - .map(v -> v.<V>map(serializer::decode)) | 345 | + .whenComplete((r, e) -> timer.stop()) |
280 | - .collect(Collectors.toList())); | 346 | + .thenApply(c -> c |
347 | + .stream() | ||
348 | + .map(v -> v.<V>map(serializer::decode)) | ||
349 | + .collect(Collectors.toList())); | ||
281 | } | 350 | } |
282 | 351 | ||
283 | @Override | 352 | @Override |
284 | public CompletableFuture<Set<Entry<K, Versioned<V>>>> entrySet() { | 353 | public CompletableFuture<Set<Entry<K, Versioned<V>>>> entrySet() { |
285 | - return database.mapEntrySet(name).thenApply(s -> s | 354 | + final OperationTimer timer = startTimer(ENTRY_SET); |
286 | - .stream() | 355 | + return database.mapEntrySet(name) |
287 | - .map(this::mapRawEntry) | 356 | + .whenComplete((r, e) -> timer.stop()) |
288 | - .collect(Collectors.toSet())); | 357 | + .thenApply(s -> s |
358 | + .stream() | ||
359 | + .map(this::mapRawEntry) | ||
360 | + .collect(Collectors.toSet())); | ||
289 | } | 361 | } |
290 | 362 | ||
291 | @Override | 363 | @Override |
292 | public CompletableFuture<Versioned<V>> putIfAbsent(K key, V value) { | 364 | public CompletableFuture<Versioned<V>> putIfAbsent(K key, V value) { |
293 | checkNotNull(key, ERROR_NULL_KEY); | 365 | checkNotNull(key, ERROR_NULL_KEY); |
294 | checkNotNull(value, ERROR_NULL_VALUE); | 366 | checkNotNull(value, ERROR_NULL_VALUE); |
295 | - return updateAndGet(key, Match.ifNull(), Match.any(), value).thenApply(v -> v.oldValue()); | 367 | + final OperationTimer timer = startTimer(PUT_IF_ABSENT); |
368 | + return updateAndGet(key, Match.ifNull(), Match.any(), value) | ||
369 | + .whenComplete((r, e) -> timer.stop()) | ||
370 | + .thenApply(v -> v.oldValue()); | ||
296 | } | 371 | } |
297 | 372 | ||
298 | @Override | 373 | @Override |
299 | public CompletableFuture<Boolean> remove(K key, V value) { | 374 | public CompletableFuture<Boolean> remove(K key, V value) { |
300 | checkNotNull(key, ERROR_NULL_KEY); | 375 | checkNotNull(key, ERROR_NULL_KEY); |
301 | checkNotNull(value, ERROR_NULL_VALUE); | 376 | checkNotNull(value, ERROR_NULL_VALUE); |
302 | - return updateAndGet(key, Match.ifValue(value), Match.any(), null).thenApply(v -> v.updated()); | 377 | + final OperationTimer timer = startTimer(REMOVE); |
378 | + return updateAndGet(key, Match.ifValue(value), Match.any(), null) | ||
379 | + .whenComplete((r, e) -> timer.stop()) | ||
380 | + .thenApply(v -> v.updated()); | ||
303 | } | 381 | } |
304 | 382 | ||
305 | @Override | 383 | @Override |
306 | public CompletableFuture<Boolean> remove(K key, long version) { | 384 | public CompletableFuture<Boolean> remove(K key, long version) { |
307 | checkNotNull(key, ERROR_NULL_KEY); | 385 | checkNotNull(key, ERROR_NULL_KEY); |
308 | - return updateAndGet(key, Match.any(), Match.ifValue(version), null).thenApply(v -> v.updated()); | 386 | + final OperationTimer timer = startTimer(REMOVE); |
387 | + return updateAndGet(key, Match.any(), Match.ifValue(version), null) | ||
388 | + .whenComplete((r, e) -> timer.stop()) | ||
389 | + .thenApply(v -> v.updated()); | ||
309 | } | 390 | } |
310 | 391 | ||
311 | @Override | 392 | @Override |
... | @@ -313,12 +394,18 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -313,12 +394,18 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
313 | checkNotNull(key, ERROR_NULL_KEY); | 394 | checkNotNull(key, ERROR_NULL_KEY); |
314 | checkNotNull(oldValue, ERROR_NULL_VALUE); | 395 | checkNotNull(oldValue, ERROR_NULL_VALUE); |
315 | checkNotNull(newValue, ERROR_NULL_VALUE); | 396 | checkNotNull(newValue, ERROR_NULL_VALUE); |
316 | - return updateAndGet(key, Match.ifValue(oldValue), Match.any(), newValue).thenApply(v -> v.updated()); | 397 | + final OperationTimer timer = startTimer(REPLACE); |
398 | + return updateAndGet(key, Match.ifValue(oldValue), Match.any(), newValue) | ||
399 | + .whenComplete((r, e) -> timer.stop()) | ||
400 | + .thenApply(v -> v.updated()); | ||
317 | } | 401 | } |
318 | 402 | ||
319 | @Override | 403 | @Override |
320 | public CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue) { | 404 | public CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue) { |
321 | - return updateAndGet(key, Match.any(), Match.ifValue(oldVersion), newValue).thenApply(v -> v.updated()); | 405 | + final OperationTimer timer = startTimer(REPLACE); |
406 | + return updateAndGet(key, Match.any(), Match.ifValue(oldVersion), newValue) | ||
407 | + .whenComplete((r, e) -> timer.stop()) | ||
408 | + .thenApply(v -> v.updated()); | ||
322 | } | 409 | } |
323 | 410 | ||
324 | private Map.Entry<K, Versioned<V>> mapRawEntry(Map.Entry<String, Versioned<byte[]>> e) { | 411 | private Map.Entry<K, Versioned<V>> mapRawEntry(Map.Entry<String, Versioned<byte[]>> e) { |
... | @@ -331,10 +418,10 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -331,10 +418,10 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
331 | V value) { | 418 | V value) { |
332 | checkIfUnmodifiable(); | 419 | checkIfUnmodifiable(); |
333 | return database.mapUpdate(name, | 420 | return database.mapUpdate(name, |
334 | - keyCache.getUnchecked(key), | 421 | + keyCache.getUnchecked(key), |
335 | - oldValueMatch.map(serializer::encode), | 422 | + oldValueMatch.map(serializer::encode), |
336 | - oldVersionMatch, | 423 | + oldVersionMatch, |
337 | - value == null ? null : serializer.encode(value)) | 424 | + value == null ? null : serializer.encode(value)) |
338 | .thenApply(this::unwrapResult) | 425 | .thenApply(this::unwrapResult) |
339 | .thenApply(r -> r.<K, V>map(this::dK, serializer::decode)) | 426 | .thenApply(r -> r.<K, V>map(this::dK, serializer::decode)) |
340 | .whenComplete((r, e) -> { | 427 | .whenComplete((r, e) -> { |
... | @@ -392,4 +479,34 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> | ... | @@ -392,4 +479,34 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> |
392 | eventPublisher.accept(event); | 479 | eventPublisher.accept(event); |
393 | } | 480 | } |
394 | } | 481 | } |
482 | + | ||
483 | + private OperationTimer startTimer(String op) { | ||
484 | + //check if timer exist, if it doesn't creates it | ||
485 | + final Timer currTimer = perMapOpTimers.computeIfAbsent(op, timer -> | ||
486 | + metricsService.createTimer(metricsComponent, metricsFeature, op)); | ||
487 | + perOpTimers.computeIfAbsent(op, timer -> metricsService.createTimer(metricsComponent, wildcard, op)); | ||
488 | + //starts timer | ||
489 | + return new OperationTimer(currTimer.time(), op); | ||
490 | + } | ||
491 | + | ||
492 | + private class OperationTimer { | ||
493 | + private final Timer.Context context; | ||
494 | + private final String operation; | ||
495 | + | ||
496 | + public OperationTimer(Timer.Context context, String operation) { | ||
497 | + this.context = context; | ||
498 | + this.operation = operation; | ||
499 | + } | ||
500 | + | ||
501 | + public void stop() { | ||
502 | + //Stop and updates timer with specific measurements per map, per operation | ||
503 | + final long time = context.stop(); | ||
504 | + //updates timer with aggregated measurements per map | ||
505 | + perOpTimers.get(operation).update(time, TimeUnit.NANOSECONDS); | ||
506 | + //updates timer with aggregated measurements per map | ||
507 | + perMapTimer.update(time, TimeUnit.NANOSECONDS); | ||
508 | + //updates timer with aggregated measurements per all Consistent Maps | ||
509 | + cMapTimer.update(time, TimeUnit.NANOSECONDS); | ||
510 | + } | ||
511 | + } | ||
395 | } | 512 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment