@@ -43,10 +43,13 @@ protected ConcurrentLiveTimerMetric(final String name) {
43
43
@ Override
44
44
public <T , E extends Throwable > T time (ExceptionalSupplier <T , E > exceptionalSupplier ) throws E {
45
45
try {
46
- trackedMillisState .getAndUpdate (TrackedMillisState :: withIncrementedConcurrency );
46
+ trackedMillisState .getAndUpdate (existing -> existing . withIncrementedConcurrency ( nanoTimeSupplier . getAsLong ()) );
47
47
return exceptionalSupplier .get ();
48
48
} finally {
49
- trackedMillisState .getAndUpdate (TrackedMillisState ::withDecrementedConcurrency );
49
+ // lock in the actual time completed, and resolve state separately
50
+ // so that contention for recording state is not included in measurement.
51
+ final long endTime = nanoTimeSupplier .getAsLong ();
52
+ trackedMillisState .getAndUpdate (existing -> existing .withDecrementedConcurrency (endTime ));
50
53
}
51
54
}
52
55
@@ -65,13 +68,13 @@ private long getUntrackedMillis() {
65
68
}
66
69
67
70
private long getTrackedMillis () {
68
- return this .trackedMillisState .getAcquire ().getValue ();
71
+ return this .trackedMillisState .getAcquire ().getValue (nanoTimeSupplier . getAsLong () );
69
72
}
70
73
71
74
interface TrackedMillisState {
72
- TrackedMillisState withIncrementedConcurrency ();
73
- TrackedMillisState withDecrementedConcurrency ();
74
- long getValue ();
75
+ TrackedMillisState withIncrementedConcurrency (long asOfNanoTime );
76
+ TrackedMillisState withDecrementedConcurrency (long asOfNanoTime );
77
+ long getValue (long asOfNanoTime );
75
78
}
76
79
77
80
private class StaticTrackedMillisState implements TrackedMillisState {
@@ -89,18 +92,18 @@ public StaticTrackedMillisState() {
89
92
}
90
93
91
94
@ Override
92
- public TrackedMillisState withIncrementedConcurrency () {
93
- return new DynamicTrackedMillisState (nanoTimeSupplier . getAsLong () , this .cumulativeMillis , this .excessNanos , 1 );
95
+ public TrackedMillisState withIncrementedConcurrency (final long asOfNanoTime ) {
96
+ return new DynamicTrackedMillisState (asOfNanoTime , this .cumulativeMillis , this .excessNanos , 1 );
94
97
}
95
98
96
99
@ Override
97
- public TrackedMillisState withDecrementedConcurrency () {
100
+ public TrackedMillisState withDecrementedConcurrency (final long asOfNanoTime ) {
98
101
throw new IllegalStateException ("TimerMetrics cannot track negative concurrency" );
99
102
}
100
103
101
104
102
105
@ Override
103
- public long getValue () {
106
+ public long getValue (final long asOfNanoTime ) {
104
107
return cumulativeMillis ;
105
108
}
106
109
}
@@ -122,26 +125,26 @@ private class DynamicTrackedMillisState implements TrackedMillisState {
122
125
}
123
126
124
127
@ Override
125
- public TrackedMillisState withIncrementedConcurrency () {
126
- return withAdjustedConcurrency (Vector .INCREMENT );
128
+ public TrackedMillisState withIncrementedConcurrency (final long asOfNanoTime ) {
129
+ return withAdjustedConcurrency (asOfNanoTime , Vector .INCREMENT );
127
130
}
128
131
129
132
@ Override
130
- public TrackedMillisState withDecrementedConcurrency () {
131
- return withAdjustedConcurrency (Vector .DECREMENT );
133
+ public TrackedMillisState withDecrementedConcurrency (final long asOfNanoTime ) {
134
+ return withAdjustedConcurrency (asOfNanoTime , Vector .DECREMENT );
132
135
}
133
136
134
137
@ Override
135
- public long getValue () {
136
- final long nanoAdjustment = getNanoAdjustment (nanoTimeSupplier . getAsLong () );
138
+ public long getValue (final long asOfNanoTime ) {
139
+ final long nanoAdjustment = getNanoAdjustment (asOfNanoTime );
137
140
final long milliAdjustment = wholeMillisFromNanos (nanoAdjustment );
138
141
139
142
return Math .addExact (this .millisAtCheckpoint , milliAdjustment );
140
143
}
141
144
142
- private TrackedMillisState withAdjustedConcurrency (final Vector concurrencyAdjustmentVector ) {
145
+ private TrackedMillisState withAdjustedConcurrency (final long asOfNanoTime , final Vector concurrencyAdjustmentVector ) {
143
146
final int newConcurrency = Math .addExact (this .concurrencySinceCheckpoint , concurrencyAdjustmentVector .value ());
144
- final long newCheckpointNanoTime = nanoTimeSupplier . getAsLong () ;
147
+ final long newCheckpointNanoTime = asOfNanoTime ;
145
148
146
149
final long totalNanoAdjustment = getNanoAdjustment (newCheckpointNanoTime );
147
150
@@ -165,7 +168,7 @@ private long getNanoAdjustment(final long checkpointNanoTime) {
165
168
166
169
/**
167
170
* This private enum is a type-safety guard for
168
- * {@link DynamicTrackedMillisState#withAdjustedConcurrency(Vector)}.
171
+ * {@link DynamicTrackedMillisState#withAdjustedConcurrency(long, Vector)}.
169
172
*/
170
173
private enum Vector {
171
174
INCREMENT { int value () { return +1 ; } },
0 commit comments