Пример #1
0
        private IndexingPerformanceStats HandleIndexingFor(IndexingBatchForIndex batchForIndex, Etag lastEtag, DateTime lastModified, CancellationToken token)
        {
            if (currentlyProcessedIndexes.TryAdd(batchForIndex.IndexId, batchForIndex.Index) == false)
            {
                Log.Error("Entered handle indexing with index {0} inside currentlyProcessedIndexes", batchForIndex.Index.PublicName);
                batchForIndex.SignalIndexingComplete();
                return null;
            }
            IndexingPerformanceStats performanceResult = null;
            var wasOutOfMemory = false;
            var wasOperationCanceled = false;
            try
            {
                transactionalStorage.Batch(actions => { performanceResult = IndexDocuments(actions, batchForIndex, token); });


                // This can be null if IndexDocument fails to execute and the exception is catched.
                if (performanceResult != null)
                    performanceResult.RunCompleted();
            }
            catch (OperationCanceledException)
            {
                wasOperationCanceled = true;
                throw;
            }
            catch (Exception e)
            {
                var exception = e;
                var aggregateException = exception as AggregateException;
                if (aggregateException != null)
                    exception = aggregateException.ExtractSingleInnerException();

                if (TransactionalStorageHelper.IsWriteConflict(exception))
                    return null;

                Log.WarnException(string.Format("Failed to index documents for index: {0}", batchForIndex.Index.PublicName), exception);

                wasOutOfMemory = TransactionalStorageHelper.IsOutOfMemoryException(exception);

                if (wasOutOfMemory == false)
                    context.AddError(batchForIndex.IndexId, batchForIndex.Index.PublicName, null, exception);
            }
            finally
            {
                if (performanceResult != null)
                {                    
                    performanceResult.OnCompleted = null;
                }				

                Index _;
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("After indexing {0} documents, the new last etag for is: {1} for {2}",
                              batchForIndex.Batch.Docs.Count,
                              lastEtag,
                              batchForIndex.Index.PublicName);
                }

                try
                {
                if (wasOutOfMemory == false && wasOperationCanceled == false)
                {
                        bool keepTrying = true;

                        for (int i = 0; i < 10 && keepTrying; i++)
                        {
                            keepTrying = false;
                    transactionalStorage.Batch(actions =>
                    {
                                try
                                {
                        // whatever we succeeded in indexing or not, we have to update this
                        // because otherwise we keep trying to re-index failed documents
                        actions.Indexing.UpdateLastIndexed(batchForIndex.IndexId, lastEtag, lastModified);
                                }
                                catch (Exception e)
                                {
                                    if (actions.IsWriteConflict(e))
                                    {
                                        keepTrying = true;
                                        return;
                                    }
                                    throw;
                                }
                    });

                            if (keepTrying)
                                Thread.Sleep(11);
                }
                    }
                else if (wasOutOfMemory)
                    HandleOutOfMemory(batchForIndex);
                }
                finally
                {
                currentlyProcessedIndexes.TryRemove(batchForIndex.IndexId, out _);
                    batchForIndex.SignalIndexingComplete();
                    batchForIndex.Index.IsMapIndexingInProgress = false;
            }
            }

            return performanceResult;
        }