From 4c4258dabad80df490110e639354f91ebdf91d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Pr=C3=B3chniak?= Date: Mon, 13 Sep 2021 12:36:49 +0200 Subject: [PATCH] More synchronization on metrics addition (#2177) --- .../util/service/GenericTimeMeasuringService.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/engine/util/src/main/scala/pl/touk/nussknacker/engine/util/service/GenericTimeMeasuringService.scala b/engine/util/src/main/scala/pl/touk/nussknacker/engine/util/service/GenericTimeMeasuringService.scala index 13fde019244..39d1cebb8f2 100644 --- a/engine/util/src/main/scala/pl/touk/nussknacker/engine/util/service/GenericTimeMeasuringService.scala +++ b/engine/util/src/main/scala/pl/touk/nussknacker/engine/util/service/GenericTimeMeasuringService.scala @@ -38,8 +38,18 @@ trait GenericTimeMeasuringService { case Failure(_) => Some("FAIL") } - private def getOrCreateTimer(tags: Map[String, String], meterType: String) : EspTimer = metrics.getOrElseUpdate(meterType, - espTimer(tags + ("serviceName" -> serviceName), metricName :+ meterType)) + private def getOrCreateTimer(tags: Map[String, String], meterType: String) : EspTimer = { + //TrieMap.getOrElseUpdate alone is not enough, as e.g. in Flink "espTimer" can be invoked only once - otherwise + //Metric may be already registered, which results in refusal to register metric without feedback. In such case + //we can end up using not-registered metric. + //The first check is for optimization purposes - to synchronize only at the beginnning + metrics.get(meterType) match { + case Some(value) => value + case None => synchronized { + metrics.getOrElseUpdate(meterType, espTimer(tags + ("serviceName" -> serviceName), metricName :+ meterType)) + } + } + } def espTimer(tags: Map[String, String], metricName: NonEmptyList[String]) : EspTimer