Skip to content

Commit 9397b18

Browse files
authored
Fix azure-search-document flaky test (Azure#36795)
Fix azure-search-document flaky test
1 parent 5d71496 commit 9397b18

File tree

5 files changed

+805
-762
lines changed

5 files changed

+805
-762
lines changed

sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/implementation/batching/SearchIndexingPublisher.java

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
import java.time.Duration;
2828
import java.util.ArrayList;
2929
import java.util.Collection;
30+
import java.util.Deque;
3031
import java.util.HashSet;
32+
import java.util.Iterator;
3133
import java.util.LinkedList;
3234
import java.util.List;
3335
import java.util.Objects;
3436
import java.util.Set;
37+
import java.util.concurrent.ConcurrentLinkedDeque;
3538
import java.util.concurrent.Semaphore;
3639
import java.util.concurrent.ThreadLocalRandom;
3740
import java.util.concurrent.atomic.AtomicInteger;
@@ -69,14 +72,14 @@ public final class SearchIndexingPublisher<T> {
6972
private final Function<Integer, Integer> scaleDownFunction = size -> size / 2;
7073

7174
private final Object actionsMutex = new Object();
72-
private final LinkedList<TryTrackingIndexAction<T>> actions = new LinkedList<>();
75+
private final Deque<TryTrackingIndexAction<T>> actions = new ConcurrentLinkedDeque<>();
7376

7477
/*
7578
* This queue keeps track of documents that are currently being sent to the service for indexing. This queue is
7679
* resilient against cases where the request timeouts or is cancelled by an external operation, preventing the
7780
* documents from being lost.
7881
*/
79-
private final LinkedList<TryTrackingIndexAction<T>> inFlightActions = new LinkedList<>();
82+
private final Deque<TryTrackingIndexAction<T>> inFlightActions = new ConcurrentLinkedDeque<>();
8083

8184
private final Semaphore processingSemaphore = new Semaphore(1);
8285

@@ -157,11 +160,9 @@ public synchronized Mono<Void> addActions(Collection<IndexAction<T>> actions, Co
157160
public Mono<Void> flush(boolean awaitLock, boolean isClose, Context context) {
158161
if (awaitLock) {
159162
processingSemaphore.acquireUninterruptibly();
160-
return flushLoop(isClose, context)
161-
.doFinally(ignored -> processingSemaphore.release());
163+
return Mono.using(() -> processingSemaphore, ignored -> flushLoop(isClose, context), Semaphore::release);
162164
} else if (processingSemaphore.tryAcquire()) {
163-
return flushLoop(isClose, context)
164-
.doFinally(ignored -> processingSemaphore.release());
165+
return Mono.using(() -> processingSemaphore, ignored -> flushLoop(isClose, context), Semaphore::release);
165166
} else {
166167
LOGGER.verbose("Batch already in-flight and not waiting for completion. Performing no-op.");
167168
return Mono.empty();
@@ -224,21 +225,21 @@ private List<TryTrackingIndexAction<T>> createBatch() {
224225
return batchActions;
225226
}
226227

227-
private int fillFromQueue(List<TryTrackingIndexAction<T>> batch, List<TryTrackingIndexAction<T>> queue,
228+
private static <T> int fillFromQueue(List<TryTrackingIndexAction<T>> batch, Deque<TryTrackingIndexAction<T>> queue,
228229
int requested, Set<String> duplicateKeyTracker) {
229-
int offset = 0;
230230
int actionsAdded = 0;
231-
int queueSize = queue.size();
232231

233-
while (actionsAdded < requested && offset < queueSize) {
234-
TryTrackingIndexAction<T> potentialDocumentToAdd = queue.get(offset++ - actionsAdded);
232+
Iterator<TryTrackingIndexAction<T>> iterator = queue.iterator();
233+
while (actionsAdded < requested && iterator.hasNext()) {
234+
TryTrackingIndexAction<T> potentialDocumentToAdd = iterator.next();
235235

236236
if (duplicateKeyTracker.contains(potentialDocumentToAdd.getKey())) {
237237
continue;
238238
}
239239

240240
duplicateKeyTracker.add(potentialDocumentToAdd.getKey());
241-
batch.add(queue.remove(offset - 1 - actionsAdded));
241+
batch.add(potentialDocumentToAdd);
242+
iterator.remove();
242243
actionsAdded += 1;
243244
}
244245

@@ -330,7 +331,7 @@ private void handleResponse(List<TryTrackingIndexAction<T>> actions, IndexBatchR
330331
return;
331332
}
332333

333-
List<TryTrackingIndexAction<T>> actionsToRetry = new ArrayList<>();
334+
Deque<TryTrackingIndexAction<T>> actionsToRetry = new LinkedList<>();
334335
boolean has503 = batchResponse.getStatusCode() == HttpURLConnection.HTTP_UNAVAILABLE;
335336
if (batchResponse.getResults() == null) {
336337
/*
@@ -391,6 +392,13 @@ private void handleResponse(List<TryTrackingIndexAction<T>> actions, IndexBatchR
391392
}
392393
}
393394

395+
private void reinsertFailedActions(Deque<TryTrackingIndexAction<T>> actionsToRetry) {
396+
synchronized (actionsMutex) {
397+
// Push all actions that need to be retried back into the queue.
398+
actionsToRetry.descendingIterator().forEachRemaining(actions::add);
399+
}
400+
}
401+
394402
private void reinsertFailedActions(List<TryTrackingIndexAction<T>> actionsToRetry) {
395403
synchronized (actionsMutex) {
396404
// Push all actions that need to be retried back into the queue.

sdk/search/azure-search-documents/src/main/java/com/azure/search/documents/indexes/SearchIndexAsyncClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ public SearchAsyncClient getSearchAsyncClient(String indexName) {
114114
.buildAsyncClient();
115115
}
116116

117-
static SearchClientBuilder getSearchClientBuilder(String indexName, String endpoint, SearchServiceVersion serviceVersion, HttpPipeline httpPipeline, JsonSerializer serializer) {
117+
static SearchClientBuilder getSearchClientBuilder(String indexName, String endpoint,
118+
SearchServiceVersion serviceVersion, HttpPipeline httpPipeline, JsonSerializer serializer) {
118119
return new SearchClientBuilder()
119120
.endpoint(endpoint)
120121
.indexName(indexName)

0 commit comments

Comments
 (0)