Skip to content

Commit 4e39304

Browse files
committed
Better lifecycle for async callbacks
1 parent c45930b commit 4e39304

7 files changed

Lines changed: 210 additions & 0 deletions

File tree

api/all/src/main/java/io/opentelemetry/api/metrics/DoubleCounterBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.BiConsumer;
89
import java.util.function.Consumer;
910

1011
/**
@@ -56,6 +57,34 @@ public interface DoubleCounterBuilder {
5657
*/
5758
ObservableDoubleCounter buildWithCallback(Consumer<ObservableDoubleMeasurement> callback);
5859

60+
/**
61+
* Builds an Asynchronous Counter instrument with the given callback.
62+
*
63+
* <p>The callback will be called when the instrument is being observed, with {@code obj} passed
64+
* as the first argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
65+
* automatic cleanup when the measured object is garbage collected.
66+
*
67+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
68+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
69+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
70+
*
71+
* <p>Callbacks are expected to abide by the following restrictions:
72+
*
73+
* <ul>
74+
* <li>Run in a finite amount of time.
75+
* <li>Safe to call repeatedly, across multiple threads.
76+
* </ul>
77+
*
78+
* @param obj The measured object. The callback receives this as its first argument.
79+
* @param callback A callback which observes measurements when invoked.
80+
* @param <T> The type of the measured object.
81+
*/
82+
@SuppressWarnings("InconsistentOverloads")
83+
default <T> ObservableDoubleCounter buildWithCallback(
84+
T obj, BiConsumer<T, ObservableDoubleMeasurement> callback) {
85+
return buildWithCallback(measurement -> callback.accept(obj, measurement));
86+
}
87+
5988
/**
6089
* Build an observer for this instrument to observe values from a {@link BatchCallback}.
6190
*

api/all/src/main/java/io/opentelemetry/api/metrics/DoubleGaugeBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.BiConsumer;
89
import java.util.function.Consumer;
910

1011
/**
@@ -52,6 +53,34 @@ public interface DoubleGaugeBuilder {
5253
*/
5354
ObservableDoubleGauge buildWithCallback(Consumer<ObservableDoubleMeasurement> callback);
5455

56+
/**
57+
* Builds an Asynchronous Gauge instrument with the given callback.
58+
*
59+
* <p>The callback will be called when the instrument is being observed, with {@code obj} passed
60+
* as the first argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
61+
* automatic cleanup when the measured object is garbage collected.
62+
*
63+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
64+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
65+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
66+
*
67+
* <p>Callbacks are expected to abide by the following restrictions:
68+
*
69+
* <ul>
70+
* <li>Run in a finite amount of time.
71+
* <li>Safe to call repeatedly, across multiple threads.
72+
* </ul>
73+
*
74+
* @param obj The measured object. The callback receives this as its first argument.
75+
* @param callback A callback which observes measurements when invoked.
76+
* @param <T> The type of the measured object.
77+
*/
78+
@SuppressWarnings("InconsistentOverloads")
79+
default <T> ObservableDoubleGauge buildWithCallback(
80+
T obj, BiConsumer<T, ObservableDoubleMeasurement> callback) {
81+
return buildWithCallback(measurement -> callback.accept(obj, measurement));
82+
}
83+
5584
/**
5685
* Build an observer for this instrument to observe values from a {@link BatchCallback}.
5786
*

api/all/src/main/java/io/opentelemetry/api/metrics/DoubleUpDownCounterBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.BiConsumer;
89
import java.util.function.Consumer;
910

1011
/**
@@ -56,6 +57,34 @@ public interface DoubleUpDownCounterBuilder {
5657
*/
5758
ObservableDoubleUpDownCounter buildWithCallback(Consumer<ObservableDoubleMeasurement> callback);
5859

60+
/**
61+
* Builds an Asynchronous UpDownCounter instrument with the given callback.
62+
*
63+
* <p>The callback will be called when the instrument is being observed, with {@code obj} passed
64+
* as the first argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
65+
* automatic cleanup when the measured object is garbage collected.
66+
*
67+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
68+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
69+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
70+
*
71+
* <p>Callbacks are expected to abide by the following restrictions:
72+
*
73+
* <ul>
74+
* <li>Run in a finite amount of time.
75+
* <li>Safe to call repeatedly, across multiple threads.
76+
* </ul>
77+
*
78+
* @param obj The measured object. The callback receives this as its first argument.
79+
* @param callback A callback which observes measurements when invoked.
80+
* @param <T> The type of the measured object.
81+
*/
82+
@SuppressWarnings("InconsistentOverloads")
83+
default <T> ObservableDoubleUpDownCounter buildWithCallback(
84+
T obj, BiConsumer<T, ObservableDoubleMeasurement> callback) {
85+
return buildWithCallback(measurement -> callback.accept(obj, measurement));
86+
}
87+
5988
/**
6089
* Build an observer for this instrument to observe values from a {@link BatchCallback}.
6190
*

api/all/src/main/java/io/opentelemetry/api/metrics/LongCounterBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.BiConsumer;
89
import java.util.function.Consumer;
910

1011
/**
@@ -60,6 +61,34 @@ public interface LongCounterBuilder {
6061
*/
6162
ObservableLongCounter buildWithCallback(Consumer<ObservableLongMeasurement> callback);
6263

64+
/**
65+
* Builds an Asynchronous Counter instrument with the given callback.
66+
*
67+
* <p>The callback will be called when the instrument is being observed, with {@code obj} passed
68+
* as the first argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
69+
* automatic cleanup when the measured object is garbage collected.
70+
*
71+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
72+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
73+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
74+
*
75+
* <p>Callbacks are expected to abide by the following restrictions:
76+
*
77+
* <ul>
78+
* <li>Run in a finite amount of time.
79+
* <li>Safe to call repeatedly, across multiple threads.
80+
* </ul>
81+
*
82+
* @param obj The measured object. The callback receives this as its first argument.
83+
* @param callback A callback which observes measurements when invoked.
84+
* @param <T> The type of the measured object.
85+
*/
86+
@SuppressWarnings("InconsistentOverloads")
87+
default <T> ObservableLongCounter buildWithCallback(
88+
T obj, BiConsumer<T, ObservableLongMeasurement> callback) {
89+
return buildWithCallback(measurement -> callback.accept(obj, measurement));
90+
}
91+
6392
/**
6493
* Build an observer for this instrument to observe values from a {@link BatchCallback}.
6594
*

api/all/src/main/java/io/opentelemetry/api/metrics/LongGaugeBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.BiConsumer;
89
import java.util.function.Consumer;
910

1011
/**
@@ -49,6 +50,34 @@ public interface LongGaugeBuilder {
4950
*/
5051
ObservableLongGauge buildWithCallback(Consumer<ObservableLongMeasurement> callback);
5152

53+
/**
54+
* Builds an Asynchronous Gauge instrument with the given callback.
55+
*
56+
* <p>The callback will be called when the instrument is being observed, with {@code obj} passed
57+
* as the first argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
58+
* automatic cleanup when the measured object is garbage collected.
59+
*
60+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
61+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
62+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
63+
*
64+
* <p>Callbacks are expected to abide by the following restrictions:
65+
*
66+
* <ul>
67+
* <li>Run in a finite amount of time.
68+
* <li>Safe to call repeatedly, across multiple threads.
69+
* </ul>
70+
*
71+
* @param obj The measured object. The callback receives this as its first argument.
72+
* @param callback A callback which observes measurements when invoked.
73+
* @param <T> The type of the measured object.
74+
*/
75+
@SuppressWarnings("InconsistentOverloads")
76+
default <T> ObservableLongGauge buildWithCallback(
77+
T obj, BiConsumer<T, ObservableLongMeasurement> callback) {
78+
return buildWithCallback(measurement -> callback.accept(obj, measurement));
79+
}
80+
5281
/**
5382
* Build an observer for this instrument to observe values from a {@link BatchCallback}.
5483
*

api/all/src/main/java/io/opentelemetry/api/metrics/LongUpDownCounterBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.BiConsumer;
89
import java.util.function.Consumer;
910

1011
/**
@@ -59,6 +60,34 @@ public interface LongUpDownCounterBuilder {
5960
*/
6061
ObservableLongUpDownCounter buildWithCallback(Consumer<ObservableLongMeasurement> callback);
6162

63+
/**
64+
* Builds an Asynchronous UpDownCounter instrument with the given callback.
65+
*
66+
* <p>The callback will be called when the instrument is being observed, with {@code obj} passed
67+
* as the first argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
68+
* automatic cleanup when the measured object is garbage collected.
69+
*
70+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
71+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
72+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
73+
*
74+
* <p>Callbacks are expected to abide by the following restrictions:
75+
*
76+
* <ul>
77+
* <li>Run in a finite amount of time.
78+
* <li>Safe to call repeatedly, across multiple threads.
79+
* </ul>
80+
*
81+
* @param obj The measured object. The callback receives this as its first argument.
82+
* @param callback A callback which observes measurements when invoked.
83+
* @param <T> The type of the measured object.
84+
*/
85+
@SuppressWarnings("InconsistentOverloads")
86+
default <T> ObservableLongUpDownCounter buildWithCallback(
87+
T obj, BiConsumer<T, ObservableLongMeasurement> callback) {
88+
return buildWithCallback(measurement -> callback.accept(obj, measurement));
89+
}
90+
6291
/**
6392
* Build an observer for this instrument to observe values from a {@link BatchCallback}.
6493
*

api/all/src/main/java/io/opentelemetry/api/metrics/Meter.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import java.util.function.Consumer;
89
import javax.annotation.concurrent.ThreadSafe;
910

1011
/**
@@ -145,4 +146,39 @@ default BatchCallback batchCallback(
145146
return DefaultMeter.getInstance()
146147
.batchCallback(callback, observableMeasurement, additionalMeasurements);
147148
}
149+
150+
/**
151+
* Creates a batch callback with the given measured object.
152+
*
153+
* <p>The callback will be called when the instruments are being observed, with {@code obj} passed
154+
* as the argument. This allows the SDK to hold a weak reference to {@code obj}, enabling
155+
* automatic cleanup when the measured object is garbage collected.
156+
*
157+
* <p>The {@code obj} should be an independently-rooted object that the application holds for its
158+
* own purposes (e.g. a connection pool, service instance, or cache). When the application drops
159+
* its strong reference to {@code obj}, the SDK may automatically remove the callback.
160+
*
161+
* <p>Callbacks are expected to abide by the following restrictions:
162+
*
163+
* <ul>
164+
* <li>Run in a finite amount of time.
165+
* <li>Safe to call repeatedly, across multiple threads.
166+
* <li>Only observe values to registered instruments (i.e. {@code observableMeasurement} and
167+
* {@code additionalMeasurements}
168+
* </ul>
169+
*
170+
* @param obj The measured object. The callback receives this as its argument.
171+
* @param callback a callback used to observe values on-demand.
172+
* @param observableMeasurement Instruments for which the callback may observe values.
173+
* @param additionalMeasurements Instruments for which the callback may observe values.
174+
* @param <T> The type of the measured object.
175+
*/
176+
@SuppressWarnings("InconsistentOverloads")
177+
default <T> BatchCallback batchCallback(
178+
T obj,
179+
Consumer<T> callback,
180+
ObservableMeasurement observableMeasurement,
181+
ObservableMeasurement... additionalMeasurements) {
182+
return batchCallback(() -> callback.accept(obj), observableMeasurement, additionalMeasurements);
183+
}
148184
}

0 commit comments

Comments
 (0)