示例#1
0
        private void UpdateDependencies(IndexItemModel item, string destinationId)
        {
            using (var entityRepository = ResolverFactory.Resolve <EntityRepository>())
                using (var attributeRepository = ResolverFactory.Resolve <AttributeRepository>())
                {
                    if (_indexerModel.EntityType == EntityType.Entity)
                    {
                        // Update Attribute Mapping (DestinationId) if _indexerModel is Entity
                        var attrs = attributeRepository.GetByEntityId(_indexerModel.Id.ToString());
                        foreach (var attr in attrs)
                        {
                            Report($"Updating destination ID for attribute {attr.Name}.");
                            if (!attributeRepository.Initialized(attr))
                            {
                                Report($"Attribute {attr.Name} is not initialized.");
                                continue;
                            }

                            if (attr.HasState(EntityState.Disabled))
                            {
                                Report($"Attribute {attr.Name} is Disabled.");
                                continue;
                            }

                            attributeRepository.UpdateItemDestinationId(attr, item.GetSourceId(), destinationId);
                            Report($"Done updating destination ID for attribute {attr.Name}.");
                        }
                    }

                    var dependencies = entityRepository.GetDependenciesOn(_indexerModel.Id, _indexerModel.EntityType);
                    foreach (var dependency in dependencies)
                    {
                        if (dependency.HasDependOnStep(IntegrationStep.Pushing | IntegrationStep.Pushing))
                        {
                            if (dependency.HasExecutionStep(IntegrationStep.Indexing | IntegrationStep.Indexed))
                            {
                                // Only add the signal to tell that the dependant entity should be pull (via PullNext) based on this item
                                entityRepository.AddPullDependency(
                                    dependency.EntityId,
                                    dependency.EntityType,
                                    _indexerModel.Id,
                                    _indexerModel.EntityType,
                                    item.GetId());
                            }
                        }
                    }
                }
        }
示例#2
0
        public async Task <PushState> PushItem(IndexItemModel item)
        {
            Report($@"
---------------------------------------------------------------------------------
Begin synchronizing item {JsonConvert.SerializeObject(item, Formatting.Indented)}...");
            var synchronizerFactory = ResolverFactory.Resolve <SynchronizerFactory>();
            var pusher = synchronizerFactory.CreatePusher(_indexerModel);

            pusher.OnReport(m => Report(m));
            var result = await Task.Run(() =>
            {
                var entityRepository    = ResolverFactory.Resolve <EntityRepository>();
                var attributeRepository = ResolverFactory.Resolve <AttributeRepository>();
                var messageRepository   = ResolverFactory.Resolve <MessageRepository>();

                try
                {
                    entityRepository.BeginTransaction();
                    attributeRepository.BeginTransaction();
                    messageRepository.BeginTransaction();
                    var pushState     = PushState.Success;
                    var destinationId = item.GetDestinationId();
                    if (!string.IsNullOrWhiteSpace(destinationId))
                    {
                        if (item.HasState(ItemState.Removed))
                        {
                            pushState = pusher.Remove();
                        }
                        else
                        {
                            pushState = pusher.Update();
                        }
                    }
                    else
                    {
                        destinationId = pusher.GetDestinationId();
                        if (!string.IsNullOrWhiteSpace(destinationId))
                        {
                            if (item.HasState(ItemState.Removed))
                            {
                                pushState = pusher.Remove(destinationId);
                            }
                            else
                            {
                                pushState = pusher.Update(destinationId);
                            }
                        }
                        else // still cannot find a destinationId, which means the entity/attribute does not exists
                        {
                            pushState = pusher.Create(out destinationId);
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(destinationId) && (pushState & PushState.Success) > 0)
                    {
                        entityRepository.UpdateItemDestinationId(_indexerModel, item.GetSourceId(), destinationId);
                        // Detect dependencies that depends on "Synced" step
                        UpdateDependencies(item, destinationId);
                    }
                    else
                    {
                        // Signal to tell that the item is success or not
                        entityRepository.Retry(_indexerModel, item.GetId(), pushState);
                    }

                    entityRepository.Commit();
                    attributeRepository.Commit();
                    return(pushState);
                }
                catch
                {
                    entityRepository.RollBack();
                    attributeRepository.RollBack();
                    // Update invalid item
                    // Increate retry count
                    // Next time when queue items, it will be put behind because of the retry count
                    entityRepository.Retry(_indexerModel, item.GetId(), PushState.UnexpectedError);
                    throw;
                }
                finally
                {
                    entityRepository?.Dispose();
                    attributeRepository?.Dispose();
                    messageRepository?.Dispose();
                    pusher?.Dispose();
                    Report($@"
Ended synchronizing...
---------------------------------------------------------------------------------
");
                }
            });

            return(result);
        }