public static void WaitForIndexNotStale(this DocumentDatabase db, string indexName, DateTime?cutOff, Guid?cuttOfEtag, TimeSpan timeout, CancellationToken cancellationToken) { TimeSpan delayIncrement = TimeSpan.FromMilliseconds(50); TimeSpan currentDelay = TimeSpan.FromMilliseconds(100); DateTime initialTime = DateTime.UtcNow; DateTime timeLimit = initialTime.Add(timeout); while (db.IsIndexStale(indexName, cutOff, cuttOfEtag)) { cancellationToken.ThrowIfCancellationRequested(); if (DateTime.UtcNow > timeLimit) { log.Error("WaitForIndexNotStale timed out after {0}", DateTime.UtcNow.Subtract(initialTime)); throw new TimeoutException("Timeout exceeded waiting for index not to be stale"); } var delayTask = TaskExtensions.Delay(currentDelay, cancellationToken); try { delayTask.Wait(); } catch (Exception ex) { if (delayTask.IsCanceled) { log.Trace("WaitForIndexNotStale has been cancelled after {0}", DateTime.UtcNow.Subtract(initialTime)); throw new OperationCanceledException(cancellationToken); } else { log.ErrorException("WaitForIndexNotStale failed", ex); throw; } } currentDelay = currentDelay.Add(delayIncrement); } log.Debug("WaitForIndexNotStale completed in {0}", DateTime.UtcNow.Subtract(initialTime)); }