예제 #1
0
        internal FluentNHibernateDistributedLock Acquire()
        {
            var finish = DateTime.Now.Add(_timeout);

            while (true)
            {
                _cancellationToken.ThrowIfCancellationRequested();


                if (SqlUtil.WrapForTransaction(() =>
                {
                    lock (Mutex)
                    {
                        using (var session = _storage.GetSession())
                        {
                            using (var transaction = session.BeginTransaction(IsolationLevel.Serializable))
                            {
                                var utcNow = session.Storage.UtcNow;
                                var count = session.CreateQuery(SqlUtil.GetCreateDistributedLockStatement())
                                            .SetParameter(SqlUtil.ResourceParameterName, _resource)
                                            .SetParameter(SqlUtil.ExpireAtAsLongParameterName,
                                                          utcNow.Add(_timeout).ToUnixDate())
                                            .SetParameter(SqlUtil.NowParameterName, utcNow)
                                            .SetParameter(SqlUtil.NowAsLongParameterName, utcNow.ToUnixDate());


                                if (count.ExecuteUpdate() > 0)
                                {
                                    transaction.Commit();
                                    return(true);
                                }
                            }
                        }
                    }

                    return(false);
                }))
                {
                    Logger.DebugFormat("Granted distributed lock for {0}", _resource);
                    _acquired = true;
                    return(this);
                }

                if (finish > DateTime.Now)
                {
                    _cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses);
                }
                else
                {
                    throw new FluentNHibernateDistributedLockException("cannot acquire lock");
                }
            }
        }
        public void Execute(CancellationToken cancellationToken)
        {
            DateTime cutOffDate;

            using (var session = _storage.GetSession())
            {
                cutOffDate = session.Storage.UtcNow;
            }

            var actionQueue = new ExpirationActionQueue(_storage, cutOffDate, cancellationToken);

            actionQueue.EnqueueDeleteJobDetailEntity <_JobState>();
            actionQueue.EnqueueDeleteJobDetailEntity <_JobQueue>();
            actionQueue.EnqueueDeleteJobDetailEntity <_JobParameter>();


            actionQueue.EnqueueDeleteEntities <_DistributedLock>((session, cutoff) =>
            {
                var unixDate = cutoff.ToUnixDate();
                var idList   = session.Query <_DistributedLock>()
                               .Where(i => i.ExpireAtAsLong < unixDate)
                               .Select(i => i.Id)
                               .ToList();
                return(session.DeleteByInt32Id <_DistributedLock>(idList));
            });
            actionQueue.EnqueueDeleteExpirableEntity <_AggregatedCounter>();
            actionQueue.EnqueueDeleteExpirableEntity <_Job>();
            actionQueue.EnqueueDeleteExpirableEntity <_List>();
            actionQueue.EnqueueDeleteExpirableEntity <_Set>();
            actionQueue.EnqueueDeleteExpirableEntity <_Hash>();

            actionQueue.Run();

            cancellationToken.WaitHandle.WaitOne(_storage.Options.JobExpirationCheckInterval);
        }
예제 #3
0
        private void EnqueueBatchDelete <T>(List <Action> actions, CancellationToken cancellationToken,
                                            Func <SessionWrapper, long> deleteFunc)

        {
            actions.Add(() =>
            {
                try
                {
                    var entityName = typeof(T).Name;
                    Logger.InfoFormat("Removing outdated records from table '{0}'...", entityName);

                    long removedCount = 0;

                    while (true)
                    {
                        try
                        {
                            using (new FluentNHibernateDistributedLock(_storage, DistributedLockKey, DefaultLockTimeout,
                                                                       cancellationToken).Acquire())
                            {
                                using (var session = _storage.GetSession())
                                {
                                    removedCount = deleteFunc(session);
                                }
                            }

                            Logger.InfoFormat("removed records count={0}", removedCount);
                        }
                        catch (FluentNHibernateDistributedLockException)
                        {
                            // do nothing
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex.ToString());
                        }


                        if (removedCount <= 0)
                        {
                            break;
                        }

                        Logger.Info(string.Format("Removed {0} outdated record(s) from '{1}' table.", removedCount,
                                                  entityName));

                        cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses);
                        cancellationToken.ThrowIfCancellationRequested();
                    }
                }
                catch (Exception) when(cancellationToken.IsCancellationRequested)
                {
                    //do nothing
                }
            });
        }
예제 #4
0
        public void EnqueueDeleteEntities <T>(Func <SessionWrapper, DateTime, long> deleteFunc)

        {
            Enqueue(() =>
            {
                try
                {
                    var entityName = typeof(T).Name;
                    Logger.InfoFormat("Removing outdated records from table '{0}'...", entityName);

                    long removedCount = 0;

                    while (true)
                    {
                        try
                        {
                            using (new FluentNHibernateDistributedLock(_storage, ExpirationManager.DistributedLockKey,
                                                                       ExpirationManager.DefaultLockTimeout,
                                                                       _cancellationToken).Acquire())
                            {
                                using (var session = _storage.GetSession())
                                {
                                    removedCount = deleteFunc(session, _cutOffDate);
                                }
                            }

                            Logger.InfoFormat("removed records count={0}", removedCount);
                        }
                        catch (FluentNHibernateDistributedLockException ex)
                        {
                            Logger.Warn(string.Concat("Can't delete : ", ex.ToString()));
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex.ToString());
                        }


                        if (removedCount <= 0)
                        {
                            break;
                        }

                        Logger.Info(string.Format("Removed {0} outdated record(s) from '{1}' table.", removedCount,
                                                  entityName));

                        _cancellationToken.WaitHandle.WaitOne(ExpirationManager.DelayBetweenPasses);
                        _cancellationToken.ThrowIfCancellationRequested();
                    }
                }
                catch (Exception) when(_cancellationToken.IsCancellationRequested)
                {
                    Logger.Warn("Cancellation was requested");
                }
            });
        }
예제 #5
0
        public void Execute(CancellationToken cancellationToken)
        {
            var      actions = new List <Action>();
            DateTime jobExpireDate;

            using (var session = _storage.GetSession())
            {
                jobExpireDate = session.Storage.UtcNow;
            }

            EnqueueBatchDeleteJobChild <_JobState>(actions, cancellationToken, jobExpireDate);
            EnqueueBatchDeleteJobChild <_JobQueue>(actions, cancellationToken, jobExpireDate);
            EnqueueBatchDeleteJobChild <_JobParameter>(actions, cancellationToken, jobExpireDate);


            EnqueueBatchDelete <_DistributedLock>(actions, cancellationToken, session =>
            {
                var idList = session.Query <_DistributedLock>()
                             .Where(i => i.ExpireAtAsLong < jobExpireDate.ToUnixDate())
                             .Select(i => i.Id)
                             .ToList();
                return(session.DeleteByInt32Id <_DistributedLock>(idList));
            });
            EnqueueBatchDelete <_AggregatedCounter>(actions, cancellationToken,
                                                    DeleteExpirableWithId <_AggregatedCounter>);
            EnqueueBatchDelete <_Job>(actions, cancellationToken, DeleteExpirableWithId <_Job>);
            EnqueueBatchDelete <_List>(actions, cancellationToken, DeleteExpirableWithId <_List>);
            EnqueueBatchDelete <_Set>(actions, cancellationToken, DeleteExpirableWithId <_Set>);
            EnqueueBatchDelete <_Hash>(actions, cancellationToken, DeleteExpirableWithId <_Hash>);

            foreach (var action in actions)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }

                action();
            }

            cancellationToken.WaitHandle.WaitOne(_checkInterval);
        }