I have an issue on which I need to run .register
at most one time on a multi-threaded env, so i tried to use ConcurrentHashMap but seems like its not thread-safe or I'm using it correctly
object NonFunctionalMetrics {
val histograms = new ConcurrentHashMap[String, Histogram](10).asScala
def workerProcessingHistogram(name: String): Histogram = {
val histogramName = s"${prefix}_${name.toSnakeCase}_processing_time"
histograms.getOrElseUpdate(
key = histogramName,
op = Histogram.build(histogramName, s"${name} worker processing time in microseconds")
.labelNames("status")
.linearBuckets(config.service.metrics.http.histogramStart, config.service.metrics.http.histogramWidth, config.service.metrics.http.histogramCount)
.register()
)
}
}
throws me exception
Collector already registered that provides name: my_app_new_site_exclusion_worker_processing_time_count
on:
val onSuccessHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelSuccess()
val onFailureHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelFailure()
When I'm adding synchronized
its working greats, as follows:
def workerProcessingHistogram(name: String): Histogram = synchronized {
val histogramName = s"${prefix}_${name.toSnakeCase}_processing_time"
histograms.getOrElseUpdate(
key = histogramName,
op = Histogram.build(histogramName, s"${name} worker processing time in microseconds")
.labelNames("status")
.linearBuckets(config.service.metrics.http.histogramStart, config.service.metrics.http.histogramWidth, config.service.metrics.http.histogramCount)
.register()
)
}
I saw that the get(key)
two threads are getting false
answer and create the histogram with register
- doesn't the ConcurrentHashMap need to handle those scenarios?
workerProcessingHistogram
function is not. You first create the name and then access the histogram. So, it's not an atomic operation.synchronized
keyword syncs on the class. So, every call is "serialized" (not happening in parallel). UNfortunately, I am not up to date about possible alternatives, that will perform better for you.