示例#1
0
        public async Task TimeoutsAreNotRemovedIfTheyAreNotMarkedAsComplete()
        {
            var theFuture = DateTimeOffset.Now.AddMinutes(1);

            await _timeoutManager.Defer(theFuture, HeadersWith("i know u"), EmptyBody());

            RebusTimeMachine.FakeIt(theFuture + TimeSpan.FromSeconds(1));

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(1));
            }

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(1));

                // mark as complete
                dueTimeoutsInTheFuture[0].MarkAsCompleted();
            }

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(0));
            }
        }
示例#2
0
        public async Task UpdatesTimeOfLastRead()
        {
            const string knownId = "known id";

            using (var source = new MemoryStream(new byte[0]))
            {
                await _storage.Save(knownId, source);
            }

            var hadLastReadTime = (await _storage.ReadMetadata(knownId)).ContainsKey(MetadataKeys.ReadTime);

            Assert.That(hadLastReadTime, Is.False, "Did not expect the {0} key to be set", MetadataKeys.ReadTime);

            var justSomeTime = new DateTimeOffset(1.January(2016));

            RebusTimeMachine.FakeIt(justSomeTime);

            _storage.Read(knownId).Result.Dispose();

            var metadata = await _storage.ReadMetadata(knownId);

            Assert.That(metadata.ContainsKey(MetadataKeys.ReadTime), Is.True);

            var readTimeMetadata = metadata[MetadataKeys.ReadTime];
            var readTime         = DateTimeOffset.Parse(readTimeMetadata);

            Assert.That(readTime, Is.EqualTo(justSomeTime),
                        $"Expected that the '{MetadataKeys.ReadTime}' metadata value '{readTimeMetadata}' would equal {justSomeTime} when passed to DateTimeOffset.Parse(...)");
        }
示例#3
0
        /// <summary>
        /// Queries the underlying table and returns due timeouts, removing them at the same time
        /// </summary>
        public DueTimeoutsResult GetDueTimeouts()
        {
            var dueTimeouts = new List <DueTimeout>();

            using (var connection = factory.OpenConnection())
                using (var command = connection.CreateCommand())
                {
                    const string sql = @"
SELECT ""id"", ""time_to_return"", ""correlation_id"", ""saga_id"", ""reply_to"", ""custom_data""
FROM ""{0}""
WHERE ""time_to_return"" <= @current_time
ORDER BY ""time_to_return"" ASC
";

                    command.CommandText = string.Format(sql, timeoutsTableName);

                    command.AddParameter("current_time", RebusTimeMachine.Now());

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var sqlTimeout = DueAdoNetTimeout.Create(MarkAsProcessed, timeoutsTableName, reader);

                            dueTimeouts.Add(sqlTimeout);
                        }
                    }
                }

            return(new DueTimeoutsResult(dueTimeouts));
        }
示例#4
0
        public IEnumerable <Timeout.Timeout> RemoveDueTimeouts()
        {
            using (var session = store.OpenSession())
            {
                var dueTimeouts = session.Query <RavenTimeout>()
                                  .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                                  .Where(x => x.Time <= RebusTimeMachine.Now()).OrderBy(x => x.Time)
                                  .ToList();

                foreach (var timeout in dueTimeouts)
                {
                    var loadedTimeout = session.Load <RavenTimeout>(timeout.Id);
                    session.Delete(loadedTimeout);
                }

                var rebusTimeouts = dueTimeouts.Select(storedTimeout =>
                                                       new Timeout.Timeout

                {
                    CorrelationId = storedTimeout.CorrelationId,
                    SagaId        = storedTimeout.SagaId,
                    TimeToReturn  = storedTimeout.Time,
                    CustomData    = storedTimeout.Data,
                    ReplyTo       = storedTimeout.ReplyTo
                }).ToList();
                session.SaveChanges();
                return(rebusTimeouts);
            }
        }
示例#5
0
        /// <summary>
        /// Retrieves all due timeouts
        /// </summary>
        public DueTimeoutsResult GetDueTimeouts()
        {
            lock (listLock)
            {
                var timeoutsToRemove = timeouts
                                       .Where(t => RebusTimeMachine.Now() >= t.TimeToReturn)
                                       .ToList();

                log.Debug("Returning {0} timeouts", timeoutsToRemove.Count);

                return(new DueTimeoutsResult(timeoutsToRemove
                                             .Select(t => new DueInMemoryTimeout(t.ReplyTo,
                                                                                 t.CorrelationId,
                                                                                 t.TimeToReturn,
                                                                                 t.SagaId,
                                                                                 t.CustomData,
                                                                                 () =>
                {
                    lock (listLock)
                    {
                        log.Debug("Removing timeout {0} -> {1}: {2}", t.TimeToReturn, t.ReplyTo, t.CustomData);

                        timeouts.Remove(t);
                    }
                }))
                                             .ToList()));
            }
        }
示例#6
0
        public IEnumerable <Timeout.Timeout> RemoveDueTimeouts()
        {
            var collection = database.GetCollection(collectionName);
            var gotResult  = true;

            do
            {
                var result = collection.FindAndRemove(Query.LTE("time", RebusTimeMachine.Now()), SortBy.Ascending("time"));

                if (result != null && result.ModifiedDocument != null)
                {
                    var document = result.ModifiedDocument;

                    yield return(new Timeout.Timeout
                    {
                        CorrelationId = document["corr_id"].AsString,
                        SagaId = document["saga_id"].AsGuid,
                        CustomData = document["data"] != BsonNull.Value ? document["data"].AsString : "",
                        ReplyTo = document["reply_to"].AsString,
                        TimeToReturn = document["time"].AsDateTime,
                    });
                }
                else
                {
                    gotResult = false;
                }
            } while (gotResult);
        }
        public async Task TimeoutsAreNotRemovedIfTheyAreNotMarkedAsComplete()
        {
            var theFuture = RebusTime.Now.AddMinutes(1);

            await _timeoutManager.Defer(theFuture, HeadersWith("i know u"), EmptyBody());

            RebusTimeMachine.FakeIt(theFuture + TimeSpan.FromSeconds(1));

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(1), "Did not get the expected number of timeouts - debug info: {0}", _factory.GetDebugInfo());
            }

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(1), "Did not get the expected number of timeouts - debug info: {0}", _factory.GetDebugInfo());

                // mark as complete
                await dueTimeoutsInTheFuture[0].MarkAsCompleted();
            }

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(0), "Did not get the expected number of timeouts - debug info: {0}", _factory.GetDebugInfo());
            }
        }
        public DueTimeoutsResult GetDueTimeouts()
        {
            using (var session = store.OpenSession())
            {
                var now = RebusTimeMachine.Now();

                var dueTimeouts = session.Query <RavenTimeout>()
                                  .Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
                                  .Where(x => x.Time <= now).OrderBy(x => x.Time)
                                  .ToList();

                var rebusTimeouts = dueTimeouts
                                    .Select(storedTimeout =>
                                            new DueRavenTimeout(storedTimeout.ReplyTo,
                                                                storedTimeout.CorrelationId,
                                                                storedTimeout.Time,
                                                                storedTimeout.SagaId,
                                                                storedTimeout.Data,
                                                                store,
                                                                storedTimeout.Id))
                                    .ToList();

                session.SaveChanges();

                return(new DueTimeoutsResult(rebusTimeouts));
            }
        }
示例#9
0
        public async Task CanGetStandardMetada()
        {
            var fakeTime = new DateTimeOffset(17.June(2016));

            RebusTimeMachine.FakeIt(fakeTime);

            const string knownId = "known id";

            var data = new byte[] { 1, 2, 3 };

            using (var source = new MemoryStream(data))
            {
                await _storage.Save(knownId, source);
            }

            var readMetadata = await _storage.ReadMetadata(knownId);

            // special case: zipped data has different size (and is actually bigger in this case :))
            if (_storage is ZippingDataBusStorageDecorator)
            {
                Assert.That(readMetadata[MetadataKeys.Length], Is.EqualTo("23"));
            }
            else
            {
                Assert.That(readMetadata[MetadataKeys.Length], Is.EqualTo("3"));
            }
            Assert.That(readMetadata[MetadataKeys.SaveTime], Is.EqualTo(fakeTime.ToString("O")));
        }
示例#10
0
        /// <summary>
        /// Internal send method - this one must not change the headers!
        /// </summary>
        internal void InternalSend(List <string> destinations, Message messageToSend, ITransactionContext transactionContext, bool published = false)
        {
            messageLogger.LogSend(destinations, messageToSend);

            var transportMessage = serializeMessages.Serialize(messageToSend);

            InternalSend(destinations, transportMessage, transactionContext);

            if (configureAdditionalBehavior.AuditMessages && published)
            {
                transportMessage.Headers[Headers.AuditReason] = Headers.AuditReasons.Published;

                if (configureAdditionalBehavior.OneWayClientMode)
                {
                    transportMessage.Headers[Headers.AuditPublishedByOneWayClient] = "";
                }
                else
                {
                    transportMessage.Headers[Headers.AuditSourceQueue] = GetInputQueueAddress();
                }

                transportMessage.Headers[Headers.AuditMessageCopyTime] = RebusTimeMachine.Now().ToString("u");
                var auditQueueName = configureAdditionalBehavior.AuditQueueName;

                InternalSend(new List <string> {
                    auditQueueName
                }, transportMessage, transactionContext);

                events.RaiseMessageAudited(this, transportMessage);
            }
        }
示例#11
0
        public void _SetUp()
        {
            RebusTimeMachine.Reset();

            _disposables.Clear();

            SetUp();
        }
示例#12
0
        /// <summary>
        /// Queries the underlying table and returns due timeouts, removing them at the same time
        /// </summary>
        public DueTimeoutsResult GetDueTimeouts()
        {
            var connection = new SqlConnection(connectionString);

            connection.Open();
            var transaction = connection.BeginTransaction();

            var dueTimeouts = new List <DueTimeout>();

            using (var command = connection.CreateCommand())
            {
                command.Transaction = transaction;
                command.CommandText =
                    string.Format(
                        @"
select 
    id, 
    time_to_return, 
    correlation_id, 
    saga_id, 
    reply_to, 
    custom_data 

from [{0}] with (updlock, readpast, rowlock)

where time_to_return <= @current_time 

order by time_to_return asc
",
                        timeoutsTableName);

                command.Parameters.AddWithValue("current_time", RebusTimeMachine.Now());

                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var id            = (long)reader["id"];
                        var correlationId = (string)reader["correlation_id"];
                        var sagaId        = (Guid)reader["saga_id"];
                        var replyTo       = (string)reader["reply_to"];
                        var timeToReturn  = (DateTime)reader["time_to_return"];
                        var customData    = (string)(reader["custom_data"] != DBNull.Value ? reader["custom_data"] : "");

                        var sqlTimeout = new DueSqlTimeout(id, replyTo, correlationId, timeToReturn, sagaId, customData, timeoutsTableName, connection, transaction);

                        dueTimeouts.Add(sqlTimeout);
                    }
                }

                return(new DueTimeoutsResult(dueTimeouts, () =>
                {
                    transaction.Commit();
                    transaction.Dispose();
                    connection.Dispose();
                }));
            }
        }
示例#13
0
        public void _SetUp()
        {
            RebusTimeMachine.Reset();

            AdjustLogging(LogLevel.Debug);

            _disposables.Clear();

            SetUp();
        }
示例#14
0
        public IEnumerable <Timeout.Timeout> RemoveDueTimeouts()
        {
            lock (listLock)
            {
                var timeoutsToRemove = timeouts.Where(t => RebusTimeMachine.Now() >= t.TimeToReturn).ToList();

                timeoutsToRemove.ForEach(t => timeouts.Remove(t));

                return(timeoutsToRemove);
            }
        }
示例#15
0
        /// <summary>
        /// Gets all timeouts that are due by now. Doesn't remove the timeouts or change them or anything,
        /// each individual timeout can be marked as processed by calling <see cref="DueTimeout.MarkAsProcessed"/>
        /// </summary>
        public IEnumerable <DueTimeout> GetDueTimeouts()
        {
            var result = collection.Find(Query.LTE(TimeProperty, RebusTimeMachine.Now()))
                         .SetSortOrder(SortBy.Ascending(TimeProperty));

            return(result
                   .Select(r => new DueMongoTimeout(r[ReplyToProperty].AsString,
                                                    GetString(r, CorrIdProperty),
                                                    r[TimeProperty].ToUniversalTime(),
                                                    GetGuid(r, SagaIdProperty),
                                                    GetString(r, DataProperty),
                                                    collection,
                                                    (ObjectId)r[IdProperty])));
        }
        public async Task GetQueueVisibilityDelayOrNull_StillReturnsPositiveTimespans()
        {
            var sendInstant = DateTimeOffset.Now;
            var deferDate   = sendInstant.AddMilliseconds(350);

            RebusTimeMachine.FakeIt(sendInstant);
            var result = AzureStorageQueuesTransport.GetQueueVisibilityDelayOrNull(new Dictionary <string, string>
            {
                { Headers.DeferredUntil, deferDate.ToString("O") }
            });

            RebusTimeMachine.Reset();
            Assert.AreEqual(result, TimeSpan.FromMilliseconds(350));
        }
示例#17
0
        static void PossiblyCopyToAuditQueue(string auditQueueName, Exception exceptionOrNull, IBus bus, ReceivedTransportMessage message)
        {
            // if an error occurred, don't do anything
            if (exceptionOrNull != null)
            {
                return;
            }

            // this one will always be non-null - but still
            if (TransactionContext.Current == null)
            {
                log.Warn("Auditor called outside of a proper transaction context!!! This must be an error.");
                return;
            }

            var rebusBus = bus as RebusBus;

            if (rebusBus == null)
            {
                log.Warn("Current IBus is not a RebusBus, it's a {0} - cannot use {0} for auditing, sorry!", bus.GetType().Name);
                return;
            }

            using (var txc = ManagedTransactionContext.Get())
            {
                var messageCopy = message.ToForwardableMessage();

                messageCopy.Headers[Headers.AuditReason]          = Headers.AuditReasons.Handled;
                messageCopy.Headers[Headers.AuditSourceQueue]     = rebusBus.GetInputQueueAddress();
                messageCopy.Headers[Headers.AuditMessageCopyTime] = RebusTimeMachine.Now().ToString("u");

                rebusBus.InternalSend(new List <string> {
                    auditQueueName
                }, messageCopy, txc.Context);

                var rebusEvents = rebusBus.Events as RebusEvents;
                if (rebusEvents == null)
                {
                    log.Warn(
                        "Current IRebusEvents is not a RebusEvents, it's a {0} - cannot use {0} for raising auditing events, sorry! (the message was properly audited though, it just turned out to be impossible to raise the MessageAudited event!)");
                    return;
                }

                rebusEvents.RaiseMessageAudited(rebusBus, messageCopy);
            }
        }
示例#18
0
        public void Handle(TimeoutRequest message)
        {
            var currentMessageContext = MessageContext.GetCurrent();

            var newTimeout = new Timeout
            {
                SagaId        = message.SagaId,
                CorrelationId = message.CorrelationId,
                ReplyTo       = currentMessageContext.ReturnAddress,
                TimeToReturn  = RebusTimeMachine.Now() + message.Timeout,
                CustomData    = message.CustomData,
            };

            storeTimeouts.Add(newTimeout);

            log.Info("Added new timeout: {0}", newTimeout);
        }
示例#19
0
        public void LogsAfterSilencePeriodIsOver()
        {
            var now = DateTime.UtcNow;

            var ignorant = new Ignorant
            {
                SilencePeriods = new[] { TimeSpan.FromMinutes(1) }
            };

            RebusTimeMachine.FakeIt(now);
            var first = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(1.1));
            var second = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            Assert.That(first, Is.True);
            Assert.That(second, Is.False);
        }
示例#20
0
        public IEnumerable <Timeout.Timeout> RemoveDueTimeouts()
        {
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();

                var dueTimeouts = new List <Timeout.Timeout>();

                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        string.Format(
                            @"select time_to_return, correlation_id, saga_id, reply_to, custom_data from [{0}] where time_to_return <= @current_time",
                            timeoutsTableName);

                    command.Parameters.AddWithValue("current_time", RebusTimeMachine.Now());

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var correlationId = (string)reader["correlation_id"];
                            var sagaId        = (Guid)reader["saga_id"];
                            var replyTo       = (string)reader["reply_to"];
                            var timeToReturn  = (DateTime)reader["time_to_return"];
                            var customData    = (string)(reader["custom_data"] != DBNull.Value ? reader["custom_data"] : "");

                            dueTimeouts.Add(new Timeout.Timeout
                            {
                                CorrelationId = correlationId,
                                SagaId        = sagaId,
                                ReplyTo       = replyTo,
                                TimeToReturn  = timeToReturn,
                                CustomData    = customData,
                            });
                        }
                    }
                }

                dueTimeouts.ForEach(t => DeleteTimeout(t, connection));

                return(dueTimeouts);
            }
        }
示例#21
0
        public void Handle(TimeoutRequest message)
        {
            var currentMessageContext = MessageContext.GetCurrent();

            if (string.IsNullOrWhiteSpace(currentMessageContext.ReturnAddress))
            {
                throw new InvalidOperationException("TimeoutRequest received with no ReturnAddress header set. No way to return message when timeout elapses.");
            }

            var newTimeout = new Timeout.Timeout(currentMessageContext.ReturnAddress,
                                                 message.CorrelationId,
                                                 RebusTimeMachine.Now() + message.Timeout,
                                                 message.SagaId,
                                                 message.CustomData);

            storeTimeouts.Add(newTimeout);

            log.Info("Added new timeout: {0}", newTimeout);
        }
示例#22
0
        /// <summary>
        /// Gets all timeouts that are due by now. Doesn't remove the timeouts or change them or anything,
        /// each individual timeout can be marked as processed by calling <see cref="DueTimeout.MarkAsProcessed"/>
        /// </summary>
        public IEnumerable <DueTimeout> GetDueTimeouts()
        {
            var result = collection.Find(Query.LTE(TimeProperty, RebusTimeMachine.Now()))
                         .SetSortOrder(SortBy.Ascending(TimeProperty));

            return(result
                   .Select(r => new DueMongoTimeout(r[ReplyToProperty].AsString,
                                                    r.Contains(CorrIdProperty)
                                                     ? r[CorrIdProperty].AsString
                                                     : "",
                                                    r[TimeProperty].AsDateTime,
                                                    r.Contains(SagaIdProperty)
                                                     ? r[SagaIdProperty].AsGuid
                                                     : Guid.Empty,
                                                    r.Contains(DataProperty)
                                                     ? r[DataProperty].AsString
                                                     : "",
                                                    collection,
                                                    (ObjectId)r[IdProperty])));
        }
示例#23
0
        public void ErrorTrackerRemovesAMessageWhichTimedOut()
        {
            //Arrange
            const string messageId = "testId";
            var fakeTime = RebusTimeMachine.Now();
            TimeMachine.FixTo(fakeTime);

            //Act
            errorTracker.TrackDeliveryFail(messageId, new Exception());
            errorTracker.TrackDeliveryFail(messageId, new Exception());

            TimeMachine.FixTo(fakeTime.Add(timeoutSpan));

            errorTracker.CheckForMessageTimeout();

            var errorText = errorTracker.GetErrorText(messageId);

            //Assert
            Assert.That(errorText, Is.Empty);
        }
示例#24
0
        /// <summary>
        /// Queries the underlying table and returns due timeouts, removing them at the same time
        /// </summary>
        public IEnumerable <DueTimeout> GetDueTimeouts()
        {
            var dueTimeouts = new List <DueTimeout>();
            var connection  = getConnection();

            try
            {
                using (var command = connection.CreateCommand())
                {
                    const string sql = @"
SELECT ""id"", ""time_to_return"", ""correlation_id"", ""saga_id"", ""reply_to"", ""custom_data""
FROM ""{0}""
WHERE ""time_to_return"" <= @current_time
ORDER BY ""time_to_return"" ASC
";

                    command.CommandText = string.Format(sql, timeoutsTableName);

                    command.Parameters.AddWithValue("current_time", RebusTimeMachine.Now());

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var sqlTimeout = DuePostgreSqlTimeout.Create(MarkAsProcessed, timeoutsTableName, reader);

                            dueTimeouts.Add(sqlTimeout);
                        }
                    }
                }

                connection.Commit();
            }
            finally
            {
                releaseConnection(connection);
            }

            return(dueTimeouts);
        }
示例#25
0
        public void GoesOnToNextSilencePeriodAfterTheFirstHasElapsed()
        {
            var now = DateTime.UtcNow;

            var ignorant = new Ignorant
            {
                SilencePeriods = new[]
                {
                    TimeSpan.FromMinutes(1),
                    TimeSpan.FromMinutes(10)
                }
            };

            RebusTimeMachine.FakeIt(now);
            var first = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(1.1));
            var second = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(11.1));
            var third = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(11.2));
            var fourth = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(21.2));
            var fifth = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(21.3));
            var sixth = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            Assert.That(first, Is.True);
            Assert.That(second, Is.False);
            Assert.That(third, Is.True);
            Assert.That(fourth, Is.False);
            Assert.That(fifth, Is.True);
            Assert.That(sixth, Is.False);
        }
示例#26
0
        /// <summary>
        /// Queries the underlying table and returns due timeouts, removing them at the same time
        /// </summary>
        public DueTimeoutsResult GetDueTimeouts()
        {
            var            dueTimeouts = new List <DueTimeout>();
            IDbConnection  connection  = null;
            IDbTransaction transaction = null;

            try
            {
                connection  = factory.OpenConnection();
                transaction = connection.BeginTransaction();

                using (var command = connection.CreateCommand())
                {
                    command.Transaction = transaction;
                    command.CommandText = FormatGetTimeoutsDueQuery(dialect, timeoutsTableName, batchSize);
                    command.AddParameter("current_time", RebusTimeMachine.Now());

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var sqlTimeout = DueAdoNetTimeout.Create(connection, timeoutsTableName, reader);

                            dueTimeouts.Add(sqlTimeout);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("GetDueTimeout produced an exception: {0}", ex);

                SafeDispose(transaction, "Disposing the transaction after exception produced other exception.");
                SafeDispose(connection, "Disposing the connection after exception produced other exception");
            }

            return(new DueTimeoutsResult(dueTimeouts, () => CommitAndClose(connection, transaction)));
        }
        public async Task TimeoutsAreNotReturnedUntilTheyAreActuallyDue()
        {
            var theFuture = DateTimeOffset.Now.AddMinutes(1);
            var evenFurtherIntoTheFuture = DateTimeOffset.Now.AddMinutes(8);

            await _timeoutManager.Defer(theFuture, HeadersWith("i know u"), EmptyBody());

            await _timeoutManager.Defer(evenFurtherIntoTheFuture, HeadersWith("i know u too"), EmptyBody());

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsNow = result.ToList();

                Assert.That(dueTimeoutsNow.Count, Is.EqualTo(0));
            }

            RebusTimeMachine.FakeIt(theFuture);

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsInTheFuture = result.ToList();
                Assert.That(dueTimeoutsInTheFuture.Count, Is.EqualTo(1));
                Assert.That(dueTimeoutsInTheFuture[0].Headers[Headers.MessageId], Is.EqualTo("i know u"));

                await dueTimeoutsInTheFuture[0].MarkAsCompleted();
            }

            RebusTimeMachine.FakeIt(evenFurtherIntoTheFuture);

            using (var result = await _timeoutManager.GetDueMessages())
            {
                var dueTimeoutsFurtherIntoInTheFuture = result.ToList();
                Assert.That(dueTimeoutsFurtherIntoInTheFuture.Count, Is.EqualTo(1));
                Assert.That(dueTimeoutsFurtherIntoInTheFuture[0].Headers[Headers.MessageId], Is.EqualTo("i know u too"));

                await dueTimeoutsFurtherIntoInTheFuture[0].MarkAsCompleted();
            }
        }
示例#28
0
        /// <summary>
        /// Queries the underlying table and returns due timeouts, removing them at the same time
        /// </summary>
        public IEnumerable <DueTimeout> GetDueTimeouts()
        {
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();

                var dueTimeouts = new List <DueTimeout>();

                using (var command = connection.CreateCommand())
                {
                    command.CommandText =
                        string.Format(
                            @"select id, time_to_return, correlation_id, saga_id, reply_to, custom_data from [{0}] where time_to_return <= @current_time order by time_to_return asc",
                            timeoutsTableName);

                    command.Parameters.AddWithValue("current_time", RebusTimeMachine.Now());

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var id            = (long)reader["id"];
                            var correlationId = (string)reader["correlation_id"];
                            var sagaId        = (Guid)reader["saga_id"];
                            var replyTo       = (string)reader["reply_to"];
                            var timeToReturn  = (DateTime)reader["time_to_return"];
                            var customData    = (string)(reader["custom_data"] != DBNull.Value ? reader["custom_data"] : "");

                            var sqlTimeout = new DueSqlTimeout(id, replyTo, correlationId, timeToReturn, sagaId, customData, connectionString, timeoutsTableName);

                            dueTimeouts.Add(sqlTimeout);
                        }
                    }
                }

                return(dueTimeouts);
            }
        }
示例#29
0
        public void ResetsWhenResetIsCalled()
        {
            var now = DateTime.UtcNow;

            var ignorant = new Ignorant
            {
                SilencePeriods = new[] { TimeSpan.FromMinutes(1) }
            };

            RebusTimeMachine.FakeIt(now);
            var first = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(0.9));
            var second = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            ignorant.Reset();
            RebusTimeMachine.FakeIt(now + TimeSpan.FromMinutes(1.1));
            var third = ignorant.IsToBeIgnored(new ApplicationException("hej"));

            Assert.That(first, Is.True);
            Assert.That(second, Is.True);
            Assert.That(third, Is.True);
        }
示例#30
0
        public void ErrorTrackerRemovesMultipleMessagesWhichTimedOut()
        {
            //Arrange
            const string messageId = "testId";
            const string messageId2 = "testId2";
            var fakeTime = RebusTimeMachine.Now();
            TimeMachine.FixTo(fakeTime);

            //Act
            errorTracker.TrackDeliveryFail(messageId, new Exception());
            TimeMachine.FixTo(fakeTime.Add(TimeSpan.FromMinutes(10)));
            errorTracker.TrackDeliveryFail(messageId2, new Exception());
            TimeMachine.FixTo(fakeTime.AddDays(1).AddMinutes(10));

            errorTracker.CheckForMessageTimeout();

            var errorText1 = errorTracker.GetErrorText(messageId);
            var errorText2 = errorTracker.GetErrorText(messageId2);

            //Assert
            Assert.That(errorText1, Is.Empty);
            Assert.That(errorText2, Is.Empty);
        }