public HttpResponseMessage TryRecoverCorruptedIndexes() { var count = 0; foreach (var indexId in Database.IndexStorage.Indexes) { var index = Database.IndexStorage.GetIndexInstance(indexId); if (index.Priority != IndexingPriority.Error) { continue; } long taskId; var state = new OperationStateBase(); var task = Task.Run(() => { // try to recover by reopening the index - it will reset it if necessary try { index = Database.IndexStorage.ReopenCorruptedIndex(index); Database.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexPriority(index.IndexId, IndexingPriority.Normal)); index.Priority = IndexingPriority.Normal; var message = $"Index {index.PublicName} has been recovered"; Database.WorkContext.ShouldNotifyAboutWork(() => message); Database.WorkContext.NotifyAboutWork(); state.MarkCompleted(message); } catch (Exception e) { var message = $"Failed to recover the corrupted index '{index.PublicName}' by reopening it"; Log.WarnException(message, e); state.MarkFaulted(message); } }); Database.Tasks.AddTask(task, state, new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.RecoverCorruptedIndexOperation, Description = index.PublicName }, out taskId); count++; } return(GetMessageWithObject(count)); }
private void TryCreateIndexesDeletionTask() { if (interlockedLock.TryEnter() == false) { return; } if (pendingDeletions.IsEmpty) { interlockedLock.Exit(); return; } var status = new OperationStateBase(); var deleteIndexesTask = Task.Factory.StartNew(() => { try { var success = new List <string>(); var failed = new List <string>(); var sp = Stopwatch.StartNew(); while (true) { DeleteIndexTask pendingDeletion; if (pendingDeletions.TryDequeue(out pendingDeletion) == false) { break; } var result = DeleteIndex(pendingDeletion, status.MarkProgress); if (result) { success.Add(pendingDeletion.IndexName); } else { failed.Add(pendingDeletion.IndexName); } } var message = $"Finished the deletion of {success.Count + failed.Count} indexes in {sp.Elapsed}"; if (success.Count > 0) { message += $", {success.Count} successful ({string.Join(", ", success)})"; } if (failed.Count > 0) { message += $", {failed.Count} failed ({string.Join(", ", success)})"; } status.MarkCompleted(message); } finally { interlockedLock.Exit(); if (pendingDeletions.IsEmpty == false) { //handling a race condition where we get a new deletion //and exiting while thinking that the deletion will be handled TryCreateIndexesDeletionTask(); } } }, TaskCreationOptions.LongRunning); long taskId; Database.Tasks.AddTask(deleteIndexesTask, status, new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.IndexDeleteOperation, Description = "Deleting indexes" }, out taskId); }