Пример #1
0
        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));
        }
Пример #2
0
        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);
        }