コード例 #1
0
        private void UpdateCascadeReferencingCollection(ReferencingCollectionSetting rc, ReferencingCollectionOperation co)
        {
            co.StartedDate          = DateTime.UtcNow;
            co.Status               = UpdateCascadeOperationStatus.Executing;
            co.UpdatedDocumentCount = 0;
            SaveOperationSilentlyIgnoringError();             // we can continue anyway
            log.Trace("Update cascade {0} referencing document collection for update cascade operation {1} started", rc.ReferencingEntityName, operation.Id);
            try
            {
                int  updatedByIndex = 0;
                Guid lastEtag;
                do
                {
                    lastEtag = db.GetLastEtag();
                    var query = new IndexQuery
                    {
                        CutoffEtag = lastEtag,
                        Query      = string.Format("{0}:{1} AND {2}:{3}NULL TO {4}{5}", rc.ReferencedIdPropertyNameInIndex, RavenQuery.Escape(referencedDoc.Key),
                                                   rc.ReferencedEtagPropertyNameInIndex, "{", RavenQuery.Escape(Convert.ToString(referencedDoc.Etag, CultureInfo.InvariantCulture)), "}")
                    };
                    updatedByIndex = db.UpdateByIndex(rc.IndexName, query, doc => UpdateDocumentWithProgressReport(doc, co),
                                                      TimeSpan.FromHours(8), cancellationToken, null);
                } while (updatedByIndex > 0);

                db.UpdateDocumentsAfter(lastEtag, UpdateDocument, cancellationToken, null);
                co.Status = UpdateCascadeOperationStatus.CompletedSuccessfully;
                log.Trace("Update cascade {0} documents for operation {1} completed successfully. {2} documents have been updated in {3}", rc.ReferencingEntityName, operation.Id, co.UpdatedDocumentCount, co.ElapsedTime);
            }
            catch (OperationCanceledException)             // save the operation and rethrow
            {
                co.Status = UpdateCascadeOperationStatus.Canceled;
                throw;
            }
            catch (Exception ex)             // Log the error, save the operation, and move to the next.
            {
                co.ErrorMessage = ex.Message;
                co.Status       = UpdateCascadeOperationStatus.Failed;
                log.ErrorException(string.Format("Update cascade {0} documents for operation {1} failed miserably. Moving on the next one ...", rc.ReferencingEntityName, operation.Id), ex);
            }
            finally
            {
                co.CompletedDate = DateTime.UtcNow;
                if (!(services.IsShutDownInProgress && co.Status == UpdateCascadeOperationStatus.Canceled))
                {
                    SaveOperationSilentlyIgnoringError();                     // we want to preserve OperationCanceledException.
                }
            }
        }
        public void RestartNotCompletedOperations()
        {
            var lastEtag = db.GetLastEtag();

            db.WaitForIndexNotStale(UpdateCascadeOperation.ByStatusIndexName, null, lastEtag, TimeSpan.FromHours(1), CancellationToken.None);
            var indexQuery = new IndexQuery
            {
                CutoffEtag = lastEtag,
                PageSize   = 1024,
                Query      = "Status:Pending OR Status:Executing"
            };
            IList <string> docIds = null;
            int            restartedOperations = 0;

            do
            {
                docIds            = db.QueryDocumentIds(UpdateCascadeOperation.ByStatusIndexName, indexQuery, CancellationToken.None);
                indexQuery.Start += docIds.Count;
                db.TransactionalStorage.Batch(_ =>
                {
                    foreach (var id in docIds)
                    {
                        var operation = repository.Get(id);
                        JsonDocument referenceDocument = null;
                        if (operation != null)
                        {
                            referenceDocument = db.Get(operation.ReferencedDocId, null);
                        }

                        if (operation != null && referenceDocument != null && TryStartOperation(operation, referenceDocument))
                        {
                            restartedOperations++;
                            log.Debug("Operation {0} has been restarted after a reboot. {1} operations restarted so far", id, restartedOperations);
                        }
                    }
                });
            } while (docIds.Count == indexQuery.PageSize);
        }