1

Will updating a micrometer gauge ever block the calling thread (eg perform I/O)?

I believe the answer is "no, I/O happens in a separate metrics collection thread" but would like to know of exceptions to this, edge cases, ..

Thanks Tarik

tariksbl
  • 1,069
  • 6
  • 20

1 Answers1

1

It depends what do you mean by calling thread. If you mean the user thread that registers the gauge, the answer is no, at that point the method that you feed to the gauge is not even called.

If you mean the thread that will "ship" the metrics, that will be blocked. This is usually a separate thread (since most of the registries are push based) but in case of Prometheus (which is pull-based) the gauge will block the Prometheus endpoint and the thread that serves it.

For this reason, in Micrometer, instead of registering the blocking method to the gauge, you can have an intermediate "state" object that you update periodically from a separate thread (blocking) and read it from the gauge (non-blocking), e.g.:

AtomicInteger currentValue = registry.gauge("test.gauge", new AtomicInteger(0));

And you can modify the currentValue from another thread, see the docs

You can do this with any arbitrary objects, e.g.:

State state = registry.gauge("test.gauge", Collections.emptyList(), new State(), State::getValue);

Where getValue does not block just give you the latest value while on another thread you can update the value encapsulated in the State object.

Here are a few lines showing that the method you register into the gauge is blocking:

public class GaugeSample {
    public static void main(String[] args) throws InterruptedException {
        PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
        System.out.println("registering the gauge...");
        Gauge.builder("test.gauge", GaugeSample::getValue)
                .register(registry);

        System.out.println("scraping...");
        System.out.println(registry.scrape());
    }

    private static double getValue() {
        try {
            Thread.sleep(5_000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        return 42;
    }
}
Jonatan Ivanov
  • 4,895
  • 2
  • 15
  • 30