예제 #1
0
        public void Expire_ExpiresSetAndHash()
        {
            var expiration = new ConsoleExpirationTransaction(_transaction.Object);

            expiration.Expire(_consoleId, TimeSpan.FromHours(1));

            _transaction.Verify(x => x.ExpireSet(_consoleId.GetSetKey(), It.IsAny <TimeSpan>()));
            _transaction.Verify(x => x.ExpireHash(_consoleId.GetHashKey(), It.IsAny <TimeSpan>()));

            // backward compatibility:
            _transaction.Verify(x => x.ExpireSet(_consoleId.GetOldConsoleKey(), It.IsAny <TimeSpan>()));
            _transaction.Verify(x => x.ExpireHash(_consoleId.GetOldConsoleKey(), It.IsAny <TimeSpan>()));
        }
예제 #2
0
        public double?GetProgress(ConsoleId consoleId)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }

            var progress = _connection.GetValueFromHash(consoleId.GetHashKey(), "progress");

            if (string.IsNullOrEmpty(progress))
            {
                // progress value is not set
                return(null);
            }

            try
            {
                return(double.Parse(progress, CultureInfo.InvariantCulture));
            }
            catch (Exception)
            {
                // corrupted data?
                return(null);
            }
        }
예제 #3
0
        public TimeSpan GetConsoleTtl(ConsoleId consoleId)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }

            return(_connection.GetHashTtl(consoleId.GetHashKey()));
        }
예제 #4
0
        public void AddLine(ConsoleId consoleId, ConsoleLine line)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }
            if (line == null)
            {
                throw new ArgumentNullException(nameof(line));
            }
            if (line.IsReference)
            {
                throw new ArgumentException("Cannot add reference directly", nameof(line));
            }

            using (var tran = _connection.CreateWriteTransaction())
            {
                // check if encoded message fits into Set's Value field

                string value;

                if (line.Message.Length > ValueFieldLimit - 36)
                {
                    // pretty sure it won't fit
                    // (36 is an upper bound for JSON formatting, TimeOffset and TextColor)
                    value = null;
                }
                else
                {
                    // try to encode and see if it fits
                    value = JobHelper.ToJson(line);

                    if (value.Length > ValueFieldLimit)
                    {
                        value = null;
                    }
                }

                if (value == null)
                {
                    var referenceKey = Guid.NewGuid().ToString("N");

                    tran.SetRangeInHash(consoleId.GetHashKey(), new[] { new KeyValuePair <string, string>(referenceKey, line.Message) });

                    line.Message     = referenceKey;
                    line.IsReference = true;

                    value = JobHelper.ToJson(line);
                }

                tran.AddToSet(consoleId.GetSetKey(), value, line.TimeOffset);

                tran.Commit();
            }
        }
예제 #5
0
        public void InitConsole_JobIdIsAddedToHash()
        {
            var storage = new ConsoleStorage(_connection.Object);

            storage.InitConsole(_consoleId);

            _connection.Verify(x => x.CreateWriteTransaction(), Times.Once);
            _transaction.Verify(x => x.SetRangeInHash(_consoleId.GetHashKey(), It2.AnyIs <KVP>(p => p.Key == "jobId")));
            _transaction.Verify(x => x.Commit(), Times.Once);
        }
예제 #6
0
        public void InitConsole(ConsoleId consoleId)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }

            // We add an extra "jobId" record into Hash for console,
            // to correctly track TTL even if console contains no lines

            _connection.SetRangeInHash(consoleId.GetHashKey(), new[] { new KeyValuePair <string, string>("jobId", consoleId.JobId) });
        }
        public void InitConsole_JobIdIsAddedToHash()
        {
            var storage = new ConsoleStorage(_connection.Object);

            storage.InitConsole(_consoleId);

            _connection.Verify(x => x.SetRangeInHash(_consoleId.GetHashKey(), It.IsAny <IEnumerable <KeyValuePair <string, string> > >()));
        }
예제 #8
0
        public IEnumerable <ConsoleLine> GetLines(ConsoleId consoleId, int start, int end)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }

            var useOldKeys = false;
            var items      = _connection.GetRangeFromSet(consoleId.GetSetKey(), start, end);

            if (items == null || items.Count == 0)
            {
                // Read operations should be backwards compatible and use
                // old keys, if new one don't contain any data.
                items      = _connection.GetRangeFromSet(consoleId.GetOldConsoleKey(), start, end);
                useOldKeys = true;
            }

            foreach (var item in items)
            {
                var line = JobHelper.FromJson <ConsoleLine>(item);

                if (line.IsReference)
                {
                    if (useOldKeys)
                    {
                        try
                        {
                            line.Message = _connection.GetValueFromHash(consoleId.GetOldConsoleKey(), line.Message);
                        }
                        catch
                        {
                            // This may happen, when using Hangfire.Redis storage and having
                            // background job, whose console session was stored using old key
                            // format.
                        }
                    }
                    else
                    {
                        line.Message = _connection.GetValueFromHash(consoleId.GetHashKey(), line.Message);
                    }

                    line.IsReference = false;
                }

                yield return(line);
            }
        }
예제 #9
0
        public void Persist(ConsoleId consoleId)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }

            _transaction.PersistSet(consoleId.GetSetKey());
            _transaction.PersistHash(consoleId.GetHashKey());

            // After upgrading to Hangfire.Console version with new keys,
            // there may be existing background jobs with console attached
            // to the previous keys. We should persist them also.
            _transaction.PersistSet(consoleId.GetOldConsoleKey());
            _transaction.PersistHash(consoleId.GetOldConsoleKey());
        }
예제 #10
0
        public void InitConsole(ConsoleId consoleId)
        {
            if (consoleId == null)
            {
                throw new ArgumentNullException(nameof(consoleId));
            }

            // We add an extra "jobId" record into Hash for console,
            // to correctly track TTL even if console contains no lines

            using (var transaction = _connection.CreateWriteTransaction())
            {
                if (!(transaction is JobStorageTransaction))
                {
                    throw new NotSupportedException("Storage tranactions must implement JobStorageTransaction");
                }

                transaction.SetRangeInHash(consoleId.GetHashKey(), new[] { new KeyValuePair <string, string>("jobId", consoleId.JobId) });

                transaction.Commit();
            }
        }