Example #1
0
        private void UpdateAnimeGroupsAndTheirContracts(ISessionWrapper session,
                                                        IReadOnlyCollection <SVR_AnimeGroup> groups)
        {
            ServerState.Instance.DatabaseBlocked = new ServerState.DatabaseBlockedInfo {
                Blocked = true, Status = "Updating statistics and contracts for AnimeGroups"
            };
            _log.Info("Updating statistics and contracts for AnimeGroups");

            var allCreatedGroupUsers = new ConcurrentBag <List <SVR_AnimeGroup_User> >();

            // Update batches of AnimeGroup contracts in parallel. Each parallel branch requires it's own session since NHibernate sessions aren't thread safe.
            // The reason we're doing this in parallel is because updating contacts does a reasonable amount of work (including LZ4 compression)
            Parallel.ForEach(groups.Batch(DefaultBatchSize), new ParallelOptions {
                MaxDegreeOfParallelism = 4
            },
                             localInit: () => DatabaseFactory.SessionFactory.OpenStatelessSession(),
                             body: (groupBatch, state, localSession) =>
            {
                var createdGroupUsers = new List <SVR_AnimeGroup_User>(groupBatch.Length);

                // We shouldn't need to keep track of updates to AnimeGroup_Users in the below call, because they should have all been deleted,
                // therefore they should all be new
                SVR_AnimeGroup.BatchUpdateStats(groupBatch, watchedStats: true, missingEpsStats: true,
                                                createdGroupUsers: createdGroupUsers);
                allCreatedGroupUsers.Add(createdGroupUsers);
                SVR_AnimeGroup.BatchUpdateContracts(localSession.Wrap(), groupBatch, updateStats: true);

                return(localSession);
            },
                             localFinally: localSession => { localSession.Dispose(); });

            _animeGroupRepo.UpdateBatch(session, groups);
            _log.Info("AnimeGroup statistics and contracts have been updated");

            ServerState.Instance.DatabaseBlocked = new ServerState.DatabaseBlockedInfo {
                Blocked = true, Status = "Creating AnimeGroup_Users and updating plex/kodi contracts"
            };
            _log.Info("Creating AnimeGroup_Users and updating plex/kodi contracts");

            List <SVR_AnimeGroup_User> animeGroupUsers = allCreatedGroupUsers.SelectMany(groupUsers => groupUsers)
                                                         .ToList();

            // Insert the AnimeGroup_Users so that they get assigned a primary key before we update plex/kodi contracts
            _animeGroupUserRepo.InsertBatch(session, animeGroupUsers);
            // We need to repopulate caches for AnimeGroup_User and AnimeGroup because we've updated/inserted them
            // and they need to be up to date for the plex/kodi contract updating to work correctly
            _animeGroupUserRepo.Populate(session, displayname: false);
            _animeGroupRepo.Populate(session, displayname: false);

            // NOTE: There are situations in which UpdatePlexKodiContracts will cause database database writes to occur, so we can't
            // use Parallel.ForEach for the time being (If it was guaranteed to only read then we'd be ok)
            foreach (SVR_AnimeGroup_User groupUser in animeGroupUsers)
            {
                groupUser.UpdatePlexKodiContracts(session);
            }

            _animeGroupUserRepo.UpdateBatch(session, animeGroupUsers);
            _log.Info("AnimeGroup_Users have been created");
        }
Example #2
0
        private void UpdateAnimeGroupsAndTheirContracts(IEnumerable <SVR_AnimeGroup> groups)
        {
            _log.Info("Updating statistics and contracts for AnimeGroups");

            var allCreatedGroupUsers = new ConcurrentBag <List <SVR_AnimeGroup_User> >();

            // Update batches of AnimeGroup contracts in parallel. Each parallel branch requires it's own session since NHibernate sessions aren't thread safe.
            // The reason we're doing this in parallel is because updating contacts does a reasonable amount of work (including LZ4 compression)
            Parallel.ForEach(groups.Batch(DefaultBatchSize), new ParallelOptions {
                MaxDegreeOfParallelism = 4
            },
                             body: (groupBatch, state, localSession) =>
            {
                var createdGroupUsers = new List <SVR_AnimeGroup_User>(groupBatch.Length);

                // We shouldn't need to keep track of updates to AnimeGroup_Users in the below call, because they should have all been deleted,
                // therefore they should all be new
                SVR_AnimeGroup.BatchUpdateStats(groupBatch, watchedStats: true, missingEpsStats: true,
                                                createdGroupUsers: createdGroupUsers);
                allCreatedGroupUsers.Add(createdGroupUsers);
                SVR_AnimeGroup.BatchUpdateContracts(groupBatch, updateStats: true);
            });

            _log.Info("AnimeGroup statistics and contracts have been updated");

            _log.Info("Creating AnimeGroup_Users and updating plex/kodi contracts");


            // Insert the AnimeGroup_Users so that they get assigned a primary key before we update plex/kodi contracts
            // We need to repopulate caches for AnimeGroup_User and AnimeGroup because we've updated/inserted them
            // and they need to be up to date for the plex/kodi contract updating to work correctly

            // NOTE: There are situations in which UpdatePlexKodiContracts will cause database database writes to occur, so we can't
            // use Parallel.ForEach for the time being (If it was guaranteed to only read then we'd be ok)
            List <int> ids = allCreatedGroupUsers.SelectMany(a => a).Select(a => a.AnimeGroup_UserID).ToList();

            using (var upd = Repo.Instance.AnimeGroup_User.BeginBatchUpdate(() => Repo.Instance.AnimeGroup_User.GetMany(ids)))
            {
                foreach (SVR_AnimeGroup_User guser in upd)
                {
                    guser.UpdatePlexKodiContracts_RA();
                    upd.Update(guser);
                }

                upd.Commit();
            }

            _log.Info("AnimeGroup_Users have been created");
        }