//Update counters
        public virtual void UpdateCounters(
            EntityContext entityContext, IList generatedEntities, bool isFlushRequired)
        {
            OrderIterationType next = _queue.Peek();

            if (entityContext.Type != next.EntityType)
            {
                throw new ArgumentException($"Type {entityContext.Type.Name} provided in {nameof(UpdateCounters)} does not match the latest action Type {next.EntityType}");
            }

            next.GenerateCount -= generatedEntities.Count;

            if (entityContext.Description.InsertToPersistentStorageBeforeUse)
            {
                //for entities that generate Id on database, will generate as much as possible before flushing.
                //the number to generate will be determined by IFlushTrigger.
                EntityProgress progress    = entityContext.EntityProgress;
                bool           isCompleted = progress.CurrentCount >= progress.TargetCount;
                if (isFlushRequired || isCompleted)
                {
                    _queue.Pop();
                }
                return;
            }

            if (next.GenerateCount <= 0)
            {
                _queue.Pop();
            }
        }
Exemplo n.º 2
0
        public virtual void SetNextReleaseCount(EntityContext entityContext)
        {
            EntityProgress progress = entityContext.EntityProgress;
            long           capacity = GetCapacity(entityContext);

            progress.NextReleaseCount = progress.ReleasedCount + capacity;
        }
 //Helper
 private EntityContext ToEntityContext(EntityProgress entityProgress)
 {
     return(new EntityContext
     {
         EntityProgress = entityProgress
     });
 }
Exemplo n.º 4
0
        public virtual bool IsFlushRequired(EntityContext entityContext)
        {
            EntityProgress progress = entityContext.EntityProgress;
            long           capacity = GetCapacity(entityContext);

            long tempStorageCount = progress.CurrentCount - progress.FlushedCount;

            return(tempStorageCount >= capacity);
        }
        //methods
        /// <summary>
        /// Update NextNodeFinder internal counters updates entity was generated
        /// </summary>
        /// <param name="updateEntityContext"></param>
        public virtual void UpdateCounters(EntityContext updateEntityContext, IList generatedEntities)
        {
            EntityProgress progress    = updateEntityContext.EntityProgress;
            bool           isCompleted = progress.TargetCount <= progress.CurrentCount;

            if (isCompleted)
            {
                NotCompletedEntities.Remove(updateEntityContext);
                CompletedEntityTypes.Add(updateEntityContext.Type);
            }
        }
Exemplo n.º 6
0
        public void AddEntityProgress(EntityInfo entityInfo, EntityProgress entityProgress)
        {
            entityProgress.DateTime  = DateTime.UtcNow;
            entityProgress.IpAddress = HttpContext.Current.Request.UserHostAddress;

            if (entityProgress.UserId == null && _userContext.IsAuthenticated)
            {
                entityProgress.UserId = _userContext.User.Id;
            }

            entityInfo.EntityProgress.Add(entityProgress);
        }
        //Flush required checks
        public virtual bool CheckIsFlushRequired(EntityContext entityContext)
        {
            EntityProgress progress          = entityContext.EntityProgress;
            bool           isFlushInProgress = progress.IsFlushInProgress();

            if (isFlushInProgress)
            {
                return(false);
            }

            //NextReleaseCount will be used by child entities to check if they still can generate from this parent
            IFlushStrategy flushTrigger = _generatorSetup.GetFlushTrigger(entityContext.Description);

            flushTrigger.SetNextReleaseCount(entityContext);

            //when all entities are generated also should flush
            bool isFlushRequired = flushTrigger.IsFlushRequired(entityContext);
            bool isCompleted     = progress.CurrentCount >= progress.TargetCount;

            if (isCompleted)
            {
                isFlushRequired = true;
            }
            if (!isFlushRequired)
            {
                //if flush is not required NextFlushCount should not be updated
                //isFlushInProgress is using NextFlushCount
                return(isFlushRequired);
            }

            //update next flush count
            flushTrigger.SetNextFlushCount(entityContext);

            //add to flush candidates if will be used by dependent children
            bool hasDependentChild = FindChildThatCanGenerate(entityContext, true) != null;

            if (hasDependentChild)
            {
                _flushCandidates.Add(entityContext);
            }

            return(isFlushRequired);
        }
        protected virtual Task[] FlushToPersistentTask(EntityContext entityContext, List <IPersistentStorage> storages)
        {
            EntityProgress progress = entityContext.EntityProgress;

            if (_entitiesAwaitingFlush.ContainsKey(entityContext.Type) == false)
            {
                return(new Task[0]);
            }

            //lock operations on list for same Type
            IList nextItems = null;

            entityContext.RunWithWriteLock(() =>
            {
                IList entitiesAwaitingFlush = _entitiesAwaitingFlush[entityContext.Type];

                long numberToFlush = progress.NextFlushCount - progress.FlushedCount;

                //take number of items to flush
                nextItems = _listOperations
                            .Take(entityContext.Type, entitiesAwaitingFlush, (int)numberToFlush);

                //remove items from temporary storage
                _entitiesAwaitingFlush[entityContext.Type] = _listOperations
                                                             .Skip(entityContext.Type, entitiesAwaitingFlush, (int)numberToFlush);

                //update progess
                progress.AddFlushedCount(nextItems.Count);
                progress.AddReleasedCount(nextItems.Count);
            });

            if (nextItems.Count == 0)
            {
                return(new Task[0]);
            }

            Task[] insertTasks = storages
                                 .Select(storage => _reflectionInvoker.InvokeInsert(storage, entityContext.Description, nextItems))
                                 .ToArray();
            return(insertTasks);
        }
        //InsertToPersistentStorageBeforeUse
        /// <summary>
        /// Insert entities to persistent storage but keep in temporary storage
        /// </summary>
        public virtual void GenerateStorageIds(EntityContext entityContext, List <IPersistentStorage> storages)
        {
            //Must be a sync operation, so inserted Ids are available immediatly
            EntityProgress progress = entityContext.EntityProgress;

            if (_entitiesAwaitingFlush.ContainsKey(entityContext.Type) == false)
            {
                return;
            }

            //lock operations on list for same Type
            IList nextItems = null;

            entityContext.RunWithReadLock(() =>
            {
                IList entitiesAwaitingFlush = _entitiesAwaitingFlush[entityContext.Type];

                long numberToSkip  = progress.FlushedCount - progress.ReleasedCount;
                long numberToFlush = progress.NextFlushCount - progress.FlushedCount;

                //skip entities that already were flushed
                nextItems = _listOperations.Skip(entityContext.Type, entitiesAwaitingFlush, (int)numberToSkip);

                //take number of items to flush
                nextItems = _listOperations.Take(entityContext.Type, nextItems, (int)numberToFlush);

                //update progress
                progress.AddFlushedCount(nextItems.Count);
            });

            if (nextItems.Count == 0)
            {
                return;
            }

            storages.ForEach(storage =>
            {
                _reflectionInvoker.InvokeInsert(storage, entityContext.Description, nextItems).Wait();
            });
        }
        public virtual void ReleaseFromTempStorage(EntityContext entityContext)
        {
            EntityProgress progress = entityContext.EntityProgress;

            if (_entitiesAwaitingFlush.ContainsKey(entityContext.Type) == false)
            {
                return;
            }

            //lock operations on list for same Type
            entityContext.RunWithWriteLock(() =>
            {
                IList entitiesAwaitingFlush = _entitiesAwaitingFlush[entityContext.Type];

                long numberToRemove = progress.NextReleaseCount - progress.ReleasedCount;

                //remove items from temporary storage
                _entitiesAwaitingFlush[entityContext.Type] = _listOperations
                                                             .Skip(entityContext.Type, entitiesAwaitingFlush, (int)numberToRemove);

                //update progress
                progress.AddReleasedCount(numberToRemove);
            });
        }