예제 #1
0
        private void Execute()
        {
            this.operation.Status = UpdateCascadeOperationStatus.Executing;
            operation.StartedDate = DateTime.UtcNow;
            operationRepository   = new Repository <UpdateCascadeOperation>(db);
            var completedReferencingEntityNames = this.operation.CollectionOperations
                                                  .Where(x => x.IsCompleted)
                                                  .Select(x => x.ReferencingEntityName)
                                                  .ToHashSet();

            var notCompletedReferencingCollections = this.setting.ReferencingCollections.Values
                                                     .Where(rc => !completedReferencingEntityNames.Contains(rc.ReferencingEntityName));

            try
            {
                log.Trace("Update cascade operation {0} started", operation.Id);
                foreach (var referencingCollectionSetting in notCompletedReferencingCollections)
                {
                    var collectionOperation = this.operation.CollectionOperations.FirstOrDefault(co => co.ReferencingEntityName == referencingCollectionSetting.ReferencingEntityName);
                    if (collectionOperation == null)
                    {
                        collectionOperation = new ReferencingCollectionOperation
                        {
                            ReferencingEntityName = referencingCollectionSetting.ReferencingEntityName
                        };
                        this.operation.CollectionOperations.Add(collectionOperation);
                    }

                    UpdateCascadeReferencingCollection(referencingCollectionSetting, collectionOperation);
                }

                operation.Status = operation.CollectionOperations.Any(co => co.Status == UpdateCascadeOperationStatus.Failed)
                                        ? UpdateCascadeOperationStatus.Failed : UpdateCascadeOperationStatus.CompletedSuccessfully;
                log.Trace("Update cascade operation {0} completed with status {1}", operation.Status);
            }
            catch (OperationCanceledException)
            {
                operation.Status = UpdateCascadeOperationStatus.Canceled;
                log.Trace("Update cascade operation {0} has been canceled", this.operation.Id);
                throw;
            }
            catch (Exception)
            {
                operation.Status = UpdateCascadeOperationStatus.Failed;
                throw;
            }
            finally
            {
                operation.CompletedDate = DateTime.UtcNow;
                if (!(services.IsShutDownInProgress && operation.Status == UpdateCascadeOperationStatus.Canceled))
                {
                    SaveOperationSilentlyIgnoringError();
                }
                operationRepository = null;
            }
        }
        private void Execute()
        {
            this.operation.Status = UpdateCascadeOperationStatus.Executing;
            operation.StartedDate = DateTime.UtcNow;
            operationRepository = new Repository<UpdateCascadeOperation>(db);
            var completedReferencingEntityNames = this.operation.CollectionOperations
                .Where( x => x.IsCompleted)
                .Select( x => x.ReferencingEntityName)
                .ToHashSet();

            var notCompletedReferencingCollections = this.setting.ReferencingCollections.Values
                .Where( rc => ! completedReferencingEntityNames.Contains( rc.ReferencingEntityName));

            try
            {
                log.Trace("Update cascade operation {0} started", operation.Id);
                foreach (var referencingCollectionSetting in notCompletedReferencingCollections)
                {
                    var collectionOperation = this.operation.CollectionOperations.FirstOrDefault(co => co.ReferencingEntityName == referencingCollectionSetting.ReferencingEntityName);
                    if (collectionOperation == null)
                    {
                        collectionOperation = new ReferencingCollectionOperation
                        {
                            ReferencingEntityName = referencingCollectionSetting.ReferencingEntityName
                        };
                        this.operation.CollectionOperations.Add(collectionOperation);
                    }

                    UpdateCascadeReferencingCollection(referencingCollectionSetting, collectionOperation);
                }

                operation.Status = operation.CollectionOperations.Any(co => co.Status == UpdateCascadeOperationStatus.Failed)
                    ? UpdateCascadeOperationStatus.Failed : UpdateCascadeOperationStatus.CompletedSuccessfully;
                log.Trace("Update cascade operation {0} completed with status {1}", operation.Status);
            }
            catch (OperationCanceledException)
            {
                operation.Status = UpdateCascadeOperationStatus.Canceled;
                log.Trace("Update cascade operation {0} has been canceled", this.operation.Id);
                throw;
            }
            catch (Exception)
            {
                operation.Status = UpdateCascadeOperationStatus.Failed;
                throw;
            }
            finally
            {
                operation.CompletedDate = DateTime.UtcNow;
                if (! (services.IsShutDownInProgress && operation.Status == UpdateCascadeOperationStatus.Canceled))
                {
                    SaveOperationSilentlyIgnoringError();
                }
                operationRepository = null;
            }
        }
 private bool UpdateDocumentWithProgressReport(JsonDocument referencingDocument, ReferencingCollectionOperation collectionOperation)
 {
     if (UpdateDocument(referencingDocument))
     {
         collectionOperation.UpdatedDocumentCount++;
         if (collectionOperation.UpdatedDocumentCount % 200 == 0)
         {
             log.Trace("Updating progress for operation {0}. {1} {2} documents have been updated so far", operation.Id, collectionOperation.UpdatedDocumentCount, collectionOperation.ReferencingEntityName);
             SaveOperationSilentlyIgnoringError(); // updating progress is not so important
         }
         return true;
     }
     else
     {
         return false;
     }
 }
        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.
            }
        }
예제 #5
0
 private bool UpdateDocumentWithProgressReport(JsonDocument referencingDocument, ReferencingCollectionOperation collectionOperation)
 {
     if (UpdateDocument(referencingDocument))
     {
         collectionOperation.UpdatedDocumentCount++;
         if (collectionOperation.UpdatedDocumentCount % 200 == 0)
         {
             log.Trace("Updating progress for operation {0}. {1} {2} documents have been updated so far", operation.Id, collectionOperation.UpdatedDocumentCount, collectionOperation.ReferencingEntityName);
             SaveOperationSilentlyIgnoringError();                     // updating progress is not so important
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #6
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.
                }
            }
        }