|
18 | 18 | import java.util.concurrent.TimeUnit; |
19 | 19 |
|
20 | 20 | import static org.hamcrest.MatcherAssert.assertThat; |
21 | | -import static org.hamcrest.Matchers.lessThanOrEqualTo; |
22 | 21 | import static org.hamcrest.Matchers.not; |
23 | 22 | import static org.hamcrest.Matchers.sameInstance; |
24 | 23 | import static org.junit.Assert.assertNotNull; |
@@ -137,59 +136,6 @@ public void getFutureAfterAggregateFiresReturnsCompletedFuture() throws Exceptio |
137 | 136 | } |
138 | 137 | } |
139 | 138 |
|
140 | | - /** |
141 | | - * Bug-proving test for the underlying leak: repeated getFuture() calls |
142 | | - * whose returned futures are then dropped (the run-loop pattern: each |
143 | | - * iteration's anyOf result becomes garbage at end of iteration) must NOT |
144 | | - * cause the pending list to grow without bound. The opportunistic prune |
145 | | - * inside getFuture() collects entries whose WeakReference target has been |
146 | | - * collected. |
147 | | - * |
148 | | - * <p>Java does not guarantee that {@link System#gc()} actually runs, but |
149 | | - * in practice with HotSpot's default GC plus a brief sleep this is |
150 | | - * reliable. If it ever flakes on CI, increase the iteration count or the |
151 | | - * sleep, or migrate to a {@code -XX:+UseSerialGC} test profile. |
152 | | - */ |
153 | | - @Test |
154 | | - public void pendingListDoesNotGrowUnboundedlyWhenFreshFuturesAreDropped() |
155 | | - throws Exception { |
156 | | - Condition fallback = new FallbackCondition(executor, 60); // never fires |
157 | | - try (FDv2DataSource.Conditions conditions = |
158 | | - new FDv2DataSource.Conditions(Collections.singletonList(fallback))) { |
159 | | - int iterations = 10_000; |
160 | | - for (int i = 0; i < iterations; i++) { |
161 | | - CompletableFuture<Object> f = conditions.getFuture(); |
162 | | - // Simulate the run loop: race f against a fast-resolving sibling. |
163 | | - // The anyOf result is awaited and discarded; f becomes unreachable |
164 | | - // at end of iteration. |
165 | | - CompletableFuture<Object> sibling = CompletableFuture.completedFuture("ok"); |
166 | | - CompletableFuture.anyOf(f, sibling).get(1, TimeUnit.SECONDS); |
167 | | - // f goes out of scope here. |
168 | | - |
169 | | - // Periodically encourage GC + give the cleanup path a chance. |
170 | | - if (i % 1000 == 999) { |
171 | | - System.gc(); |
172 | | - Thread.sleep(10); |
173 | | - } |
174 | | - } |
175 | | - System.gc(); |
176 | | - Thread.sleep(50); |
177 | | - |
178 | | - // After 10k iterations, pendingSize() should not be anywhere near |
179 | | - // 10k. The opportunistic prune inside getFuture() runs on every |
180 | | - // call, so any entry whose WeakReference has been collected drops |
181 | | - // out. A small handful (< 100) of recently-added live refs is |
182 | | - // expected because the most recent iterations may not yet have |
183 | | - // been GC'd. Choose a generous ceiling to avoid CI flakiness while |
184 | | - // still being orders of magnitude below the pre-fix accumulation. |
185 | | - int finalSize = conditions.pendingSize(); |
186 | | - assertThat( |
187 | | - "pending list size should be bounded; was " + finalSize |
188 | | - + " after " + iterations + " iterations", |
189 | | - finalSize, lessThanOrEqualTo(500)); |
190 | | - } |
191 | | - } |
192 | | - |
193 | 139 | private static FDv2SourceResult makeInterruptedResult() { |
194 | 140 | return FDv2SourceResult.interrupted( |
195 | 141 | new DataSourceStatusProvider.ErrorInfo( |
|
0 commit comments