Exemplo n.º 1
0
        /// <summary>
        /// Checks if any of the activities expired.
        /// If so, it deletes them.
        /// </summary>
        public async Task CheckExpiredActivitiesAsync()
        {
            log.Trace("()");

            DateTime      now            = DateTime.UtcNow;
            List <byte[]> imagesToDelete = new List <byte[]>();

            using (UnitOfWork unitOfWork = new UnitOfWork())
            {
                // Disable change tracking for faster multiple deletes.
                unitOfWork.Context.ChangeTracker.AutoDetectChangesEnabled = false;

                // Find and delete expired primary activities.
                DatabaseLock lockObject = UnitOfWork.PrimaryActivityLock;
                await unitOfWork.AcquireLockAsync(lockObject);

                try
                {
                    List <PrimaryActivity> expiredActivities = (await unitOfWork.PrimaryActivityRepository.GetAsync(i => i.ExpirationTime < now, null, true)).ToList();
                    if (expiredActivities.Count > 0)
                    {
                        log.Debug("There are {0} expired primary activities.", expiredActivities.Count);
                        foreach (PrimaryActivity activity in expiredActivities)
                        {
                            unitOfWork.PrimaryActivityRepository.Delete(activity);
                            log.Debug("Activity ID {0}, owner ID '{1}' expired and will be deleted.", activity.ActivityId, activity.OwnerIdentityId.ToHex());
                        }

                        await unitOfWork.SaveThrowAsync();

                        log.Debug("{0} expired primary activities were deleted.", expiredActivities.Count);
                    }
                    else
                    {
                        log.Debug("No expired primary activities found.");
                    }
                }
                catch (Exception e)
                {
                    log.Error("Exception occurred: {0}", e.ToString());
                }

                unitOfWork.ReleaseLock(lockObject);


                // Find and delete expired neighbor activities.
                lockObject = UnitOfWork.NeighborActivityLock;
                await unitOfWork.AcquireLockAsync(lockObject);

                try
                {
                    List <NeighborActivity> expiredActivities = (await unitOfWork.NeighborActivityRepository.GetAsync(i => i.ExpirationTime < now, null, true)).ToList();
                    if (expiredActivities.Count > 0)
                    {
                        log.Debug("There are {0} expired neighbor activities.", expiredActivities.Count);
                        foreach (NeighborActivity activity in expiredActivities)
                        {
                            unitOfWork.NeighborActivityRepository.Delete(activity);
                            log.Debug("Activity ID {0}, owner ID '{1}' expired and will be deleted.", activity.ActivityId, activity.OwnerIdentityId.ToHex());
                        }

                        await unitOfWork.SaveThrowAsync();

                        log.Debug("{0} expired neighbor activities were deleted.", expiredActivities.Count);
                    }
                    else
                    {
                        log.Debug("No expired neighbor activities found.");
                    }
                }
                catch (Exception e)
                {
                    log.Error("Exception occurred: {0}", e.ToString());
                }

                unitOfWork.ReleaseLock(lockObject);
            }


            log.Trace("(-)");
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks if any of the follower servers need refresh. If so, a neighborhood action is created.
        /// <para>This function also checks if there are unprocessed refresh neighborhood actions
        /// and if there are 3 such requests already, the follower is deleted as it is considered as unresponsive for too long.</para>
        /// </summary>
        public async Task CheckFollowersRefreshAsync()
        {
            log.Trace("()");

            // If a follower server's LastRefreshTime is lower than this limit, it should be refreshed.
            DateTime limitLastRefreshTime = DateTime.UtcNow.AddSeconds(-Config.Configuration.FollowerRefreshTimeSeconds);

            List <byte[]> followersToDeleteIds = new List <byte[]>();

            using (UnitOfWork unitOfWork = new UnitOfWork())
            {
                DatabaseLock[] lockObjects = new DatabaseLock[] { UnitOfWork.FollowerLock, UnitOfWork.NeighborhoodActionLock };
                await unitOfWork.AcquireLockAsync(lockObjects);

                try
                {
                    List <Follower> followersToRefresh = (await unitOfWork.FollowerRepository.GetAsync(f => f.LastRefreshTime < limitLastRefreshTime, null, true)).ToList();
                    if (followersToRefresh.Count > 0)
                    {
                        bool saveDb          = false;
                        int  actionsInserted = 0;

                        log.Debug("There are {0} followers that need refresh.", followersToRefresh.Count);
                        foreach (Follower follower in followersToRefresh)
                        {
                            int unprocessedRefreshProfileActions = await unitOfWork.NeighborhoodActionRepository.CountAsync(a => (a.ServerId == follower.NetworkId) && (a.Type == NeighborhoodActionType.RefreshNeighborStatus));

                            if (unprocessedRefreshProfileActions < 3)
                            {
                                NeighborhoodAction action = new NeighborhoodAction()
                                {
                                    ServerId              = follower.NetworkId,
                                    Type                  = NeighborhoodActionType.RefreshNeighborStatus,
                                    Timestamp             = DateTime.UtcNow,
                                    ExecuteAfter          = DateTime.UtcNow,
                                    TargetActivityId      = 0,
                                    TargetActivityOwnerId = null,
                                    AdditionalData        = null
                                };

                                await unitOfWork.NeighborhoodActionRepository.InsertAsync(action);

                                log.Debug("Refresh neighborhood action for follower ID '{0}' will be inserted to the database.", follower.NetworkId.ToHex());
                                saveDb = true;
                                actionsInserted++;
                            }
                            else
                            {
                                log.Debug("There are {0} unprocessed RefreshNeighborStatus neighborhood actions for follower ID '{1}'. Follower will be deleted.", unprocessedRefreshProfileActions, follower.NetworkId.ToHex());
                                followersToDeleteIds.Add(follower.NetworkId);
                            }
                        }

                        if (saveDb)
                        {
                            await unitOfWork.SaveThrowAsync();

                            log.Debug("{0} new neighborhood actions saved to the database.", actionsInserted);
                        }
                    }
                    else
                    {
                        log.Debug("No followers need refresh now.");
                    }
                }
                catch (Exception e)
                {
                    log.Error("Exception occurred: {0}", e.ToString());
                }

                unitOfWork.ReleaseLock(lockObjects);


                if (followersToDeleteIds.Count > 0)
                {
                    log.Debug("There are {0} followers to be deleted.", followersToDeleteIds.Count);
                    foreach (byte[] followerToDeleteId in followersToDeleteIds)
                    {
                        Iop.Shared.Status status = unitOfWork.FollowerRepository.DeleteFollowerAsync(followerToDeleteId).Result;
                        if (status == Iop.Shared.Status.Ok)
                        {
                            log.Debug("Follower ID '{0}' deleted.", followerToDeleteId.ToHex());
                        }
                        else
                        {
                            log.Warn("Unable to delete follower ID '{0}', error code {1}.", followerToDeleteId.ToHex(), status);
                        }
                    }
                }
                else
                {
                    log.Debug("No followers to delete now.");
                }
            }

            log.Trace("(-)");
        }