public void Should_set_the_next_run() { const int numberOfTimeoutsToAdd = 50; for (var i = 0; i < numberOfTimeoutsToAdd; i++) { var d = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), OwningTimeoutManager = "MyEndpoint" }; persister.Add(d); } var expected = DateTime.UtcNow.AddHours(1); persister.Add(new TimeoutData { Time = expected, OwningTimeoutManager = String.Empty, }); DateTime nextTimeToRunQuery; persister.GetNextChunk(DateTime.UtcNow.AddYears(-3), out nextTimeToRunQuery); var totalMilliseconds = (expected - nextTimeToRunQuery).Duration().TotalMilliseconds; Assert.True(totalMilliseconds < 200); }
TransportMessage MapToTransportMessage(TimeoutData timeoutData) { var transportMessage = new TransportMessage { ReplyToAddress = Address.Local, Headers = new Dictionary<string, string>(), Recoverable = true, MessageIntent = MessageIntentEnum.Send, CorrelationId = timeoutData.CorrelationId, Body = timeoutData.State }; if (timeoutData.Headers != null) { transportMessage.Headers = timeoutData.Headers; } else { //we do this to be backwards compatible, this can be removed when going to 3.1.X transportMessage.Headers[Headers.Expire] = timeoutData.Time.ToWireFormattedString(); if (timeoutData.SagaId != Guid.Empty) transportMessage.Headers[Headers.SagaId] = timeoutData.SagaId.ToString(); } return transportMessage; }
public void Handle(TransportMessage message) { if (!message.Headers.ContainsKey(NServiceBus.Headers.Expire)) { throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + message.Id); } var sagaId = Guid.Empty; if (message.Headers.ContainsKey(NServiceBus.Headers.SagaId)) { sagaId = Guid.Parse(message.Headers[NServiceBus.Headers.SagaId]); } if (message.Headers.ContainsKey(Headers.ClearTimeout)) { Manager.ClearTimeout(sagaId); Persister.Remove(sagaId); } else { var data = new TimeoutData { Destination = message.ReplyToAddress, SagaId = sagaId, State = message.Body, Time = DateTime.Parse(message.Headers[NServiceBus.Headers.Expire]) }; Manager.PushTimeout(data); Persister.Add(data); } }
private void OnSagaTimedOut(TimeoutData timeoutData) { if (SagaTimedOut != null) { SagaTimedOut(null, timeoutData); } }
public async Task Should_set_the_next_run() { const int numberOfTimeoutsToAdd = 50; for (var i = 0; i < numberOfTimeoutsToAdd; i++) { var d = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), OwningTimeoutManager = "MyEndpoint" }; await persister.Add(d, new ContextBag()); } var expected = DateTime.UtcNow.AddHours(1); await persister.Add(new TimeoutData { Time = expected, OwningTimeoutManager = string.Empty, }, new ContextBag()); var nextChunk = await GetNextChunk(); var totalMilliseconds = (expected - nextChunk.NextTimeToQuery).Duration().TotalMilliseconds; Assert.True(totalMilliseconds < 200); }
TransportMessage MapToTransportMessage(TimeoutData timeoutData) { var transportMessage = new TransportMessage { ReplyToAddress = Address.Local, Headers = new Dictionary <string, string>(), Recoverable = true, MessageIntent = MessageIntentEnum.Send, CorrelationId = timeoutData.CorrelationId, Body = timeoutData.State }; if (timeoutData.Headers != null) { transportMessage.Headers = timeoutData.Headers; } else { //we do this to be backwards compatible, this can be removed when going to 3.1.X transportMessage.Headers[Headers.Expire] = timeoutData.Time.ToWireFormattedString(); if (timeoutData.SagaId != Guid.Empty) { transportMessage.Headers[Headers.SagaId] = timeoutData.SagaId.ToString(); } } return(transportMessage); }
public void Handle(TransportMessage message) { if(!message.Headers.ContainsKey(NServiceBus.Headers.Expire)) throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + message.Id); var sagaId = Guid.Empty; if (message.Headers.ContainsKey(NServiceBus.Headers.SagaId)) sagaId = Guid.Parse(message.Headers[NServiceBus.Headers.SagaId]); if (message.Headers.ContainsKey(Headers.ClearTimeout)) { Manager.ClearTimeout(sagaId); Persister.Remove(sagaId); } else { var data = new TimeoutData { Destination = message.ReplyToAddress, SagaId = sagaId, State = message.Body, Time = DateTime.Parse(message.Headers[NServiceBus.Headers.Expire]) }; Manager.PushTimeout(data); Persister.Add(data); } }
public void Handle(TransportMessage message) { var sagaId = Guid.Empty; if (message.Headers.ContainsKey(Headers.SagaId)) sagaId = Guid.Parse(message.Headers[Headers.SagaId]); if (message.Headers.ContainsKey(Headers.ClearTimeouts)) { if(sagaId == Guid.Empty) throw new InvalidOperationException("Invalid saga id specified, clear timeouts is only supported for saga instances"); Persister.ClearTimeoutsFor(sagaId); Manager.ClearTimeout(sagaId); } else { if (!message.Headers.ContainsKey(Headers.Expire)) throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + message.Id); var data = new TimeoutData { Destination = message.ReplyToAddress, SagaId = sagaId, State = message.Body, Time = message.Headers[Headers.Expire].ToUtcDateTime(), CorrelationId = message.CorrelationId, Headers = message.Headers }; Persister.Add(data); Manager.PushTimeout(data); } }
public void Add(CoreTimeoutData timeout) { using (var session = DocumentStore.OpenSession()) { session.Store(new Timeout(timeout)); session.SaveChanges(); } }
public void When_existing_is_removed_existing_is_outted() { var persister = new InMemoryTimeoutPersister(); var inputTimeout = new TimeoutData(); persister.Add(inputTimeout); TimeoutData removedTimeout; var removed = persister.TryRemove(inputTimeout.Id, out removedTimeout); Assert.IsTrue(removed); Assert.AreSame(inputTimeout, removedTimeout); }
public async Task TryRemove_when_non_existing_is_removed_should_return_false() { var persister = new InMemoryTimeoutPersister(() => DateTime.UtcNow); var inputTimeout = new TimeoutData(); await persister.Add(inputTimeout, new ContextBag()); var result = await persister.TryRemove(Guid.NewGuid().ToString(), new ContextBag()); Assert.False(result); }
public async Task TryRemove_when_existing_is_removed_should_return_true() { var persister = new InMemoryTimeoutPersister(() => DateTime.UtcNow); var inputTimeout = new TimeoutData(); await persister.Add(inputTimeout, new ContextBag()); var result = await persister.TryRemove(inputTimeout.Id, new ContextBag()); Assert.IsTrue(result); }
void IManageTimeouts.PushTimeout(TimeoutData timeout) { lock (data) { if (!data.ContainsKey(timeout.Time)) data[timeout.Time] = new List<TimeoutData>(); data[timeout.Time].Add(timeout); } }
void IManageTimeouts.PushTimeout(TimeoutData timeout) { lock (data) { if (!data.ContainsKey(timeout.Time)) { data[timeout.Time] = new List <TimeoutData>(); } data[timeout.Time].Add(timeout); } }
public async Task Add(CoreTimeoutData timeout, ContextBag context) { using (var session = documentStore.OpenAsyncSession()) { var timeoutData = new Timeout(timeout); await session.StoreAsync(timeoutData).ConfigureAwait(false); await session.SaveChangesAsync().ConfigureAwait(false); timeout.Id = timeoutData.Id; } }
public void PushTimeout(TimeoutData timeout) { if (timeout.Time.AddSeconds(-1) <= DateTime.UtcNow) { MessageSender.Send(timeout.ToTransportMessage(), timeout.ToSendOptions(Configure.LocalAddress)); return; } TimeoutsPersister.Add(timeout); if (TimeoutPushed != null) { TimeoutPushed(timeout); } }
public void PushTimeout(TimeoutData timeout) { if (timeout.Time.AddSeconds(-1) <= DateTime.UtcNow) { MessageSender.Send(timeout.ToTransportMessage(), timeout.Destination); return; } TimeoutsPersister.Add(timeout); if (TimeoutPushed != null) { TimeoutPushed.BeginInvoke(this, timeout, ar => {}, null); } }
public void When_existing_is_removed_by_saga_id() { var persister = new InMemoryTimeoutPersister(); var newGuid = Guid.NewGuid(); var inputTimeout = new TimeoutData { SagaId = newGuid }; persister.Add(inputTimeout); persister.RemoveTimeoutBy(newGuid); TimeoutData removedTimeout; var removed = persister.TryRemove(inputTimeout.Id, out removedTimeout); Assert.False(removed); }
public void PushTimeout(TimeoutData timeout) { if (timeout.Time.AddSeconds(-1) <= DateTime.UtcNow) { MessageSender.Send(timeout.ToTransportMessage(), timeout.ToSendOptions(Configure.LocalAddress)); return; } TimeoutsPersister.Add(timeout); if (TimeoutPushed != null) { TimeoutPushed(timeout); } }
public void PushTimeout(TimeoutData timeout) { if (timeout.Time.AddSeconds(-1) <= DateTime.UtcNow) { MessageSender.Send(timeout.ToTransportMessage(), timeout.Destination); return; } TimeoutsPersister.Add(timeout); if (TimeoutPushed != null) { TimeoutPushed.BeginInvoke(this, timeout, ar => {}, null); } }
public void TryRemove() { var timeout = new TimeoutData { Destination = "theDestination", SagaId = new Guid("ec1be111-39e5-403c-9960-f91282269455"), State = new byte[] {1}, Time = new DateTime(2000, 1, 1), Headers = new Dictionary<string, string> { {"HeaderKey", "HeaderValue"} } }; persister.Add(timeout, null).Await(); Assert.IsTrue(persister.TryRemove(timeout.Id, null).Result); Assert.IsFalse(persister.TryRemove(timeout.Id, null).Result); }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData {Id = "1", Time = DateTime.UtcNow.AddHours(-1)}; persister.Add(t1); var t2 = new TimeoutData {Id = "2", Time = DateTime.UtcNow.AddHours(-1)}; persister.Add(t2); var timeouts = GetNextChunk(); foreach (var timeout in timeouts) { TimeoutData timeoutData; persister.TryRemove(timeout.Item1, out timeoutData); } Assert.AreEqual(0, GetNextChunk().Count()); }
TransportMessage MapToTransportMessage(TimeoutData timeoutData) { var transportMessage = new TransportMessage { ReplyToAddress = Address.Local, Headers = new Dictionary<string, string>(), Recoverable = true, MessageIntent = MessageIntentEnum.Send, Body = timeoutData.State }; transportMessage.Headers[NServiceBus.Headers.Expire] = timeoutData.Time.ToString(); if(timeoutData.SagaId != Guid.Empty) transportMessage.Headers[NServiceBus.Headers.SagaId] = timeoutData.SagaId.ToString(); return transportMessage; }
public void Handle(TransportMessage message) { var sagaId = Guid.Empty; if (message.Headers.ContainsKey(Headers.SagaId)) { sagaId = Guid.Parse(message.Headers[Headers.SagaId]); } if (message.Headers.ContainsKey(Headers.ClearTimeouts)) { if (sagaId == Guid.Empty) { throw new InvalidOperationException("Invalid saga id specified, clear timeouts is only supported for saga instances"); } Persister.ClearTimeoutsFor(sagaId); Manager.ClearTimeout(sagaId); } else { if (!message.Headers.ContainsKey(Headers.Expire)) { throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + message.Id); } var data = new TimeoutData { Destination = message.ReplyToAddress, SagaId = sagaId, State = message.Body, Time = message.Headers[Headers.Expire].ToUtcDateTime(), CorrelationId = message.CorrelationId, Headers = message.Headers, OwningTimeoutManager = Configure.EndpointName }; Persister.Add(data); Manager.PushTimeout(data); } }
TransportMessage MapToTransportMessage(TimeoutData timeoutData) { var transportMessage = new TransportMessage { ReplyToAddress = Address.Local, Headers = new Dictionary <string, string>(), Recoverable = true, MessageIntent = MessageIntentEnum.Send, Body = timeoutData.State }; transportMessage.Headers[NServiceBus.Headers.Expire] = timeoutData.Time.ToString(); if (timeoutData.SagaId != Guid.Empty) { transportMessage.Headers[NServiceBus.Headers.SagaId] = timeoutData.SagaId.ToString(); } return(transportMessage); }
public void Add(TimeoutData timeout) { var id = Guid.NewGuid().ToString(); using (var conn = _connectionFactory()) { var timeoutInfo = new DynamicParameters(new { id, Destination = timeout.Destination != null ? timeout.Destination.ToString() : null, timeout.SagaId, timeout.State, timeout.Time, EndpointName }); timeoutInfo.Add("Headers", _serializer.Serialize(timeout.Headers)); conn.Execute( "INSERT INTO timeouts (id, destination, sagaid, state, time, headers, endpointname) VALUES (:Id, :Destination, :SagaId, :State, :Time, :Headers, :EndpointName)", timeoutInfo); timeout.Id = id; } }
public async Task Add(TimeoutData timeout, ContextBag context) { using (var connection = connectionBuilder()) { await connection.OpenAsync(); using (var command = connection.CreateCommand()) { command.CommandText = timeoutCommands.Add; var id = Guid.NewGuid(); timeout.Id = id.ToString(); command.AddParameter("Id", id); command.AddParameter("Destination", timeout.Destination); command.AddParameter("SagaId", timeout.SagaId); command.AddParameter("State", timeout.State); command.AddParameter("Time", timeout.Time); command.AddParameter("Headers", Serializer.Serialize(timeout.Headers)); command.AddParameter("PersistenceVersion", StaticVersions.PersistenceVersion); await command.ExecuteNonQueryEx(); } } }
public void Handle(TransportMessage message) { var sagaId = Guid.Empty; if (message.Headers.ContainsKey(Headers.SagaId)) { sagaId = Guid.Parse(message.Headers[Headers.SagaId]); } if (message.Headers.ContainsKey(Headers.ClearTimeouts)) { if (sagaId == Guid.Empty) { throw new InvalidOperationException("Invalid saga id specified, clear timeouts is only supported for saga instances"); } Manager.ClearTimeout(sagaId); Persister.Remove(sagaId); } else { if (!message.Headers.ContainsKey(Headers.Expire)) { throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + message.Id); } var data = new TimeoutData { Destination = message.ReplyToAddress, SagaId = sagaId, State = message.Body, Time = DateTime.Parse(message.Headers[Headers.Expire]) }; Manager.PushTimeout(data); Persister.Add(data); } }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { using (var conn = _connectionFactory()) { timeoutData = conn.Query( "SELECT id, destination, sagaid, state, time, headers, endpointname FROM timeouts WHERE id = :id", new {id = timeoutId}) .Select( i => new TimeoutData { Id = i.id, Destination = i.destination != null ? Address.Parse(i.destination) : null, SagaId = i.sagaid, State = i.state, Headers = _serializer.Deserialize<Dictionary<string, string>>(i.headers), OwningTimeoutManager = i.endpointname }).FirstOrDefault(); var result = timeoutData != default(TimeoutData); conn.Execute("DELETE FROM timeouts WHERE id = :id", new {id = timeoutId}); return result; } }
public bool TryRemove(string timeoutId, out CoreTimeoutData timeoutData) { using (var session = DocumentStore.OpenSession()) { session.Advanced.UseOptimisticConcurrency = true; var timeout = session.Load<Timeout>(timeoutId); if (timeout == null) { timeoutData = null; return false; } timeoutData = timeout.ToCoreTimeoutData(); session.Delete(timeout); session.SaveChanges(); return true; } }
void OnSagaTimedOut(TimeoutData timeoutData) { if (SagaTimedOut != null) SagaTimedOut(null, timeoutData); }
public async Task Peek_when_timeout_does_not_exist_should_return_null() { var persister = new InMemoryTimeoutPersister(() => DateTime.UtcNow); var inputTimeout = new TimeoutData(); await persister.Add(inputTimeout, new ContextBag()); var result = await persister.Peek(Guid.NewGuid().ToString(), new ContextBag()); Assert.IsNull(result); }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { timeoutData = null; return false; }
public void Add(TimeoutData timeout) { }
public void Peek() { var startSlice = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); var timeout1Time = startSlice.AddSeconds(1); var timeout1 = new TimeoutData { Destination = "theDestination", State = new byte[] {1}, Time = timeout1Time, Headers = new Dictionary<string, string>() }; persister.Add(timeout1, null).Await(); var nextChunk = persister.Peek(timeout1.Id, null).Result; ObjectApprover.VerifyWithJson(nextChunk, s => s.Replace(timeout1.Id, "theId")); }
public void Should_only_return_timeouts_for_this_specific_endpoint_and_any_ones_without_a_owner() { const int numberOfTimeoutsToAdd = 3; for (var i = 0; i < numberOfTimeoutsToAdd; i++) { var d = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), OwningTimeoutManager = Configure.EndpointName }; persister.Add(d); } persister.Add(new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), OwningTimeoutManager = "MyOtherTM" }); persister.Add(new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), OwningTimeoutManager = String.Empty, }); Assert.AreEqual(numberOfTimeoutsToAdd + 1, GetNextChunk().Count); }
public async Task When_existing_is_removed_by_saga_id() { var persister = new InMemoryTimeoutPersister(() => DateTime.UtcNow); var newGuid = Guid.NewGuid(); var inputTimeout = new TimeoutData { SagaId = newGuid }; await persister.Add(inputTimeout, new ContextBag()); await persister.RemoveTimeoutBy(newGuid, new ContextBag()); var result = await persister.TryRemove(inputTimeout.Id, new ContextBag()); Assert.IsFalse(result); }
public void GetNextChunk() { var startSlice = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); var timeout1Time = startSlice.AddSeconds(1); var timeout2Time = DateTime.UtcNow.AddSeconds(10); var timeout1 = new TimeoutData { Destination = "theDestination", State = new byte[] {1}, Time = timeout1Time, Headers = new Dictionary<string, string>() }; var timeout2 = new TimeoutData { Destination = "theDestination", State = new byte[] {1}, Time = timeout2Time, Headers = new Dictionary<string, string>() }; persister.Add(timeout1, null).Await(); persister.Add(timeout2, null).Await(); var nextChunk = persister.GetNextChunk(startSlice).Result; Assert.That(nextChunk.NextTimeToQuery, Is.EqualTo(timeout2Time).Within(TimeSpan.FromSeconds(1))); ObjectApprover.VerifyWithJson(nextChunk.DueTimeouts, s => s.Replace(timeout1.Id, "theId")); }
public Task Add(TimeoutData timeout, ContextBag context) { return TaskEx.CompletedTask; }
public async Task Peek_when_timeout_exists_should_return_timeout() { var persister = new InMemoryTimeoutPersister(() => DateTime.UtcNow); var inputTimeout = new TimeoutData(); await persister.Add(inputTimeout, new ContextBag()); var result = await persister.Peek(inputTimeout.Id, new ContextBag()); Assert.AreSame(inputTimeout, result); }