public void GetNextChunk() { var startSlice = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); var timeout1Time = startSlice.AddSeconds(1); var timeout2Time = goodUtcNowValue.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>() }; var persister = Setup(schema); 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))); Assert.IsNotNull(nextChunk); Assert.AreEqual(DateTimeKind.Utc, nextChunk.NextTimeToQuery.Kind); #if NET452 ObjectApprover.VerifyWithJson(nextChunk, s => s.Replace(timeout1.Id, "theId")); #endif }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { try { readerWriterLock.EnterWriteLock(); for (var index = 0; index < storage.Count; index++) { var data = storage[index]; if (data.Id == timeoutId) { timeoutData = data; storage.RemoveAt(index); return true; } } timeoutData = null; return false; } finally { readerWriterLock.ExitWriteLock(); } }
public void Add(TimeoutData timeout) { var timeoutId = Guid.Empty; string messageId; if (timeout.Headers != null && timeout.Headers.TryGetValue(Headers.MessageId, out messageId)) { Guid.TryParse(messageId, out timeoutId); } if (timeoutId == Guid.Empty) { timeoutId = CombGuidGenerator.Instance.NewCombGuid(Guid.NewGuid(), DateTime.UtcNow); } _collection.InsertOne(new TimeoutEntity { Id = timeoutId.ToString(), Destination = timeout.Destination, SagaId = timeout.SagaId, State = timeout.State, Time = timeout.Time, Headers = timeout.Headers, Endpoint = timeout.OwningTimeoutManager, OwningTimeoutManager = timeout.OwningTimeoutManager }); }
public void Add(TimeoutData timeoutData) { try { timeoutData.Id = Guid.NewGuid().ToString(); Logger.DebugFormat("Add timeoutData {0}", timeoutData.Id); var timeoutEntity = new TimeoutEntity { Id = timeoutData.Id, Destination = timeoutData.Destination != null?timeoutData.Destination.ToString() : null, SagaId = timeoutData.SagaId, State = timeoutData.State, Time = timeoutData.Time, TimeString = timeoutData.Time.ToString("O"), Headers = timeoutData.Headers, CorrelationId = timeoutData.CorrelationId, OwningTimeoutManager = timeoutData.OwningTimeoutManager }; using (var redisClient = RedisClientsManager.GetClient()) { redisClient.As <TimeoutEntity>().AddItemToSortedSet(redisClient.As <TimeoutEntity>().SortedSets[EndpointName], timeoutEntity, timeoutEntity.Time.ToUnixTimeSeconds()); Logger.InfoFormat("Added timeoutEntity {0} with score {1} to sorted set {2}", timeoutEntity.Id, timeoutEntity.Time.ToUnixTimeSeconds(), redisClient.As <TimeoutEntity>().SortedSets[EndpointName].ToUrn()); } } catch (Exception e) { Logger.Error(string.Format("ERROR Add {0}", timeoutData), e); throw; } }
public void Add(TimeoutData timeout) { Logger.Debug("Adding timeout"); if (timeout == null) { Logger.Debug("Timeout is null! Throwing"); throw new ArgumentNullException("timeout"); } Guid timeoutId = CombGuid.NewGuid(); Logger.DebugFormat("Created new comb guid for timeout ID {0}", timeoutId); TimeoutDataEntity timeoutEntity = new TimeoutDataEntity { Destination = timeout.Destination.ToString(), Endpoint = timeout.OwningTimeoutManager, Headers = timeout.Headers.ToDictionaryString(), Id = timeoutId, SagaId = timeout.SagaId, State = timeout.State, Time = timeout.Time }; using (ITimeoutDbContext dbc = _dbContextFactory.CreateTimeoutDbContext()) { Logger.Debug("Saving timeout entity"); dbc.Timeouts.Add(timeoutEntity); dbc.SaveChanges(); } }
public void Add(TimeoutData timeout) { timeout.Id = Guid.NewGuid().ToString("N"); int score = ScoreDateTime(timeout.Time); if (_log.IsDebugEnabled) { _log.Debug("Adding timeout with ID " + timeout.Id + " " + timeout.Time.ToString() + " " + score); } using (var client = GetClient()) { var nativeClient = client as RedisNativeClient; using (var tran = client.CreateTransaction()) { tran.QueueCommand(c => c.Lists[GetTimeoutIdsListName()].Add(timeout.Id)); tran.QueueCommand(c => c.Hashes[GetTimeoutDataHashName()].AddIfNotExists(new KeyValuePair <string, string>(timeout.Id, Serialize(timeout)))); tran.QueueCommand(c => ((RedisNativeClient)c).ZAdd(GetTimeoutTimesSortedSetName(), score, Encoding.UTF8.GetBytes(timeout.Id))); if (timeout.SagaId != Guid.Empty) { tran.QueueCommand(c => c.Hashes[GetSagaIdMapHashName()].AddIfNotExists(new KeyValuePair <string, string>(timeout.SagaId.ToString("N"), timeout.Id))); } tran.Commit(); } } }
static 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 bool TryRemove(string timeoutId, out TimeoutData timeoutData) { using (var client = GetClient()) { var timeoutString = client.Hashes[GetTimeoutDataHashName()][timeoutId]; if (timeoutString != null) { var timeout = Deserialize(timeoutString); timeoutData = timeout; using (var tran = client.CreateTransaction()) { tran.QueueCommand(c => c.Lists[GetTimeoutIdsListName()].Remove(timeoutId)); tran.QueueCommand(c => c.Hashes[GetTimeoutDataHashName()].Remove(timeoutId)); tran.QueueCommand(c => c.SortedSets[GetTimeoutTimesSortedSetName()].Remove(timeoutId)); tran.QueueCommand(c => c.Hashes[GetSagaIdMapHashName()].Remove(timeout.SagaId.ToString("N"))); tran.Commit(); } return(true); } else { timeoutData = null; return(false); } } }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData(); persister.Add(t1); var t2 = new TimeoutData(); persister.Add(t2); var t = persister.GetAll(); foreach (var timeoutData in t) { using (var tx = new TransactionScope()) { //other tx stuff like pop a message from MSMQ persister.Remove(timeoutData); tx.Complete(); } } using (var session = store.OpenSession()) { session.Advanced.AllowNonAuthoritativeInformation = false; Assert.Null(session.Load<TimeoutData>(t1.Id)); Assert.Null(session.Load<TimeoutData>(t2.Id)); } }
public void GetNextChunk_CleanupOnce() { var startSlice = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); var timeout1Time = startSlice.AddYears(-10); var timeout1 = new TimeoutData { Destination = "theDestination", State = new byte[] { 1 }, Time = timeout1Time, Headers = new Dictionary <string, string>() }; var persister = Setup(schema, TimeSpan.FromMinutes(2)); persister.Add(timeout1, null).Await(); //Call once triggering clean-up mode persister.GetNextChunk(startSlice).GetAwaiter().GetResult(); //Call again to check if clean-up mode is now disabled -- expect no results var nextChunk = persister.GetNextChunk(startSlice).Result; Assert.IsNotNull(nextChunk); #if NET452 ObjectApprover.VerifyWithJson(nextChunk, s => s.Replace(timeout1.Id, "theId")); #endif }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData { Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary <string, string> { { "Header1", "Value1" } } }; var t2 = new TimeoutData { Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary <string, string> { { "Header1", "Value1" } } }; persister.Add(t1); persister.Add(t2); var t = persister.GetAll(); foreach (var timeoutData in t) { persister.Remove(timeoutData.Id); } using (var session = sessionFactory.OpenSession()) { Assert.Null(session.Get <TimeoutEntity>(new Guid(t1.Id))); Assert.Null(session.Get <TimeoutEntity>(new Guid(t2.Id))); } }
public async Task <InitiTimeoutsResult> InitTimeouts(int nrOfTimeouts, string endpointName, int startFromId) { var timeoutsPrefix = "TimeoutDatas"; var shortestTimeout = DateTime.MaxValue; var longestTimeout = DateTime.MinValue; var daysToTrigger = random.Next(2, 60); // randomize the Time property var commands = new List <object>(); var bulkInsertUrl = $"{ServerName}/databases/{DatabaseName}/bulk_docs"; for (var i = 0; i < nrOfTimeouts; i++) { // Insert the timeout data var timeoutData = new TimeoutData { Destination = "WeDontCare.ThisShouldBeIgnored.BecauseItsJustForRouting", SagaId = Guid.NewGuid(), OwningTimeoutManager = endpointName, Time = DateTime.Now.AddDays(daysToTrigger), Headers = new Dictionary <string, string>(), State = Encoding.ASCII.GetBytes("This is my state") }; commands.Add(new PutCommand { Document = timeoutData, ChangeVector = null, Type = "PUT", Id = $"{timeoutsPrefix}/{startFromId + i}" }); if (shortestTimeout > timeoutData.Time) { shortestTimeout = timeoutData.Time; } if (longestTimeout < timeoutData.Time) { longestTimeout = timeoutData.Time; } } var request = new { Commands = commands.ToArray() }; var serializeObject = JsonConvert.SerializeObject(request); using var stringContent = new StringContent(serializeObject, Encoding.UTF8, "application/json"); using var result = await HttpClient.PostAsync(bulkInsertUrl, stringContent); Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.Created)); return(new InitiTimeoutsResult { ShortestTimeout = shortestTimeout, LongestTimeout = longestTimeout }); }
public async Task InitTimeouts(int nrOfTimeouts) { var commands = new List <object>(); var bulkInsertUrl = $"{ServerName}/databases/{DatabaseName}/bulk_docs"; var timeoutsPrefix = "TimeoutDatas"; for (var i = 0; i < nrOfTimeouts; i++) { // Insert the timeout data var timeoutData = new TimeoutData { Destination = "WeDontCare.ThisShouldBeIgnored.BecauseItsJustForRouting", SagaId = Guid.NewGuid(), OwningTimeoutManager = "A", Time = i < nrOfTimeouts / 2 ? DateTime.Now.AddDays(7) : DateTime.Now.AddDays(14), Headers = new Dictionary <string, string>(), State = Encoding.ASCII.GetBytes("This is my state") }; commands.Add(new { Document = timeoutData, Method = "PUT", Key = $"{timeoutsPrefix}/{i}", Metadata = new object() }); } var serializeObject = JsonConvert.SerializeObject(commands); using var stringContent = new StringContent(serializeObject, Encoding.UTF8, "application/json"); using var result = await HttpClient.PostAsync(bulkInsertUrl, stringContent); Assert.That(result.StatusCode, Is.EqualTo(HttpStatusCode.OK)); }
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 = Configure.EndpointName }; 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); }
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 void Should_remove_timeouts_by_id() { var t1 = new TimeoutData(); persister.Add(t1); var t2 = new TimeoutData(); persister.Add(t2); var t = persister.GetAll(); foreach (var timeoutData in t) { using (var tx = new TransactionScope()) { //other tx stuff like pop a message from MSMQ persister.Remove(timeoutData.Id); tx.Complete(); } } using (var session = store.OpenSession()) { session.Advanced.AllowNonAuthoritativeInformation = false; Assert.Null(session.Load <TimeoutData>(t1.Id)); Assert.Null(session.Load <TimeoutData>(t2.Id)); } }
bool TryRemoveTimeoutEntity(Guid timeoutId, IDbConnection connection, out TimeoutData timeoutData) { bool found; using (var session = SessionFactory.OpenStatelessSessionEx(connection)) { using (var tx = session.BeginAmbientTransactionAware(IsolationLevel.ReadCommitted)) { var te = session.Get <TimeoutEntity>(timeoutId); timeoutData = MapToTimeoutData(te); if (timeoutData == null) { tx.Commit(); return(false); } var queryString = string.Format("delete {0} where Id = :id", typeof(TimeoutEntity)); found = session.CreateQuery(queryString) .SetParameter("id", timeoutId) .ExecuteUpdate() > 0; tx.Commit(); } } if (!found) { timeoutData = null; return(false); } return(true); }
public void Add(TimeoutData timeout) { timeout.Id = Guid.NewGuid().ToString(); try { readerWriterLock.EnterWriteLock(); using (ITransaction tx = _context.StateManager.CreateTransaction()) { var storage = storages.GetOrAddAsync(tx, EndpointName, type => new List<TimeoutData>()).Result; storage.Add(timeout); storages.AddOrUpdateAsync(tx, EndpointName, type => new List<TimeoutData>(), (t, o) => storage).Wait(); tx.CommitAsync().Wait(); } } catch (Exception ex) { throw ex; } finally { readerWriterLock.ExitWriteLock(); } }
public async Task Peek_should_return_timeout_with_id() { var uniqueId = Guid.NewGuid().ToString(); var timeoutData = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), Destination = "timeouts", SagaId = Guid.NewGuid(), State = new byte[] { 0, 0, 133 }, Headers = new Dictionary <string, string> { { "Bar", "34234" }, { "Foo", "aString1" }, { "Super", "aString2" }, { Headers.MessageId, uniqueId } }, OwningTimeoutManager = "MyTestEndpoint" }; await persister.Add(timeoutData, new ContextBag()).ConfigureAwait(false); var result = await persister.Peek(timeoutData.Id, new ContextBag()).ConfigureAwait(false); Assert.AreEqual(timeoutData.Id, result.Id); Assert.AreEqual(timeoutData.Time.ToString("G"), result.Time.ToString("G")); Assert.AreEqual(timeoutData.Destination, result.Destination); Assert.AreEqual(timeoutData.SagaId, result.SagaId); Assert.AreEqual(timeoutData.State, result.State); Assert.AreEqual(timeoutData.Headers, result.Headers); }
public async Task When_in_transaction_scope_with_sql_connection_should_hook_up_to_that_connection() { var data = new TimeoutData { Time = DateTime.Now, OwningTimeoutManager = "MyTestEndpoint", }; var contextBag = new ContextBag(); using (var tx = new TransactionScope()) { var connection = (SqlConnection)((SessionFactoryImpl)sessionFactory).ConnectionProvider.GetConnection(); var transaction = new TransportTransaction(); transaction.Set(Transaction.Current); transaction.Set(connection); contextBag.Set(transaction); await persister.Add(data, contextBag).ConfigureAwait(false); Assert.AreEqual(Guid.Empty, Transaction.Current.TransactionInformation.DistributedIdentifier); tx.Complete(); } using (var session = sessionFactory.OpenSession()) { Assert.NotNull(session.Get <TimeoutEntity>(new Guid(data.Id))); } }
public void UseConfiguredSchema() { if (!SupportsSchemas()) { Assert.Ignore(); } 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>() }; var defaultSchemaPersister = Setup(null); var schemaPersister = Setup(schema); defaultSchemaPersister.Add(timeout1, null).Await(); var result = schemaPersister.Peek(timeout1.Id, null).Result; Assert.Null(result); }
public async Task When_in_transaction_scope_add_should_commit_when_scope_is_complete() { var data = new TimeoutData { Time = DateTime.Now.AddYears(-1), OwningTimeoutManager = "MyTestEndpoint", }; var contextBag = new ContextBag(); using (var tx = new TransactionScope()) { var transaction = new TransportTransaction(); transaction.Set(Transaction.Current); contextBag.Set(transaction); await persister.Add(data, contextBag).ConfigureAwait(false); tx.Complete(); } using (var session = sessionFactory.OpenSession()) { Assert.NotNull(session.Get <TimeoutEntity>(new Guid(data.Id))); } }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData { Time = DateTime.Now.AddYears(-1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary <string, string> { { "Header1", "Value1" } } }; var t2 = new TimeoutData { Time = DateTime.Now.AddYears(-1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary <string, string> { { "Header1", "Value1" } } }; persister.Add(t1); persister.Add(t2); DateTime nextTimeToRunQuery; var timeouts = persister.GetNextChunk(DateTime.UtcNow.AddYears(-3), out nextTimeToRunQuery); foreach (var timeout in timeouts) { TimeoutData timeoutData; persister.TryRemove(timeout.Item1, out timeoutData); } using (var session = sessionFactory.OpenSession()) { Assert.Null(session.Get <TimeoutEntity>(new Guid(t1.Id))); Assert.Null(session.Get <TimeoutEntity>(new Guid(t2.Id))); } }
public void FractionalSeconds() { var startSlice = new DateTime(2000, 1, 1, 1, 1, 1, 42, DateTimeKind.Utc); // 42ms var timeout1Time = startSlice.AddSeconds(1); var timeout2Time = goodUtcNowValue.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>() }; var persister = Setup(schema); 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))); Assert.That(nextChunk.DueTimeouts.Length, Is.EqualTo(1)); // MSSQL stores 42ms as .043 because it doesn't have millisecond precision. MySQL/Oracle store to nearest second. Assert.That(nextChunk.DueTimeouts[0].DueTime, Is.EqualTo(timeout1Time).Within(TimeSpan.FromMilliseconds(43))); }
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), }); Assert.AreEqual(numberOfTimeoutsToAdd+1, persister.GetAll().Count()); }
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); }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { try { readerWriterLock.EnterWriteLock(); for (var index = 0; index < storage.Count; index++) { var data = storage[index]; if (data.Id == timeoutId) { timeoutData = data; storage.RemoveAt(index); return(true); } } timeoutData = null; return(false); } finally { readerWriterLock.ExitWriteLock(); } }
public void Add(TimeoutData timeout) { var context = new ServiceContext(account.CreateCloudTableClient()); var hash = Hash(timeout); TimeoutDataEntity timeoutDataEntity; if (TryGetTimeoutData(context, hash, string.Empty, out timeoutDataEntity)) { return; } var stateAddress = Upload(timeout.State, hash); var headers = Serialize(timeout.Headers); if (!TryGetTimeoutData(context, timeout.Time.ToString(PartitionKeyScope), stateAddress, out timeoutDataEntity)) { context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(timeout.Time.ToString(PartitionKeyScope), stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); } timeout.Id = stateAddress; if (timeout.SagaId != default(Guid) && !TryGetTimeoutData(context, timeout.SagaId.ToString(), stateAddress, out timeoutDataEntity)) { context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(timeout.SagaId.ToString(), stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); } context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(stateAddress, string.Empty) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); context.SaveChanges(); }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData(); persister.Add(t1); var t2 = new TimeoutData(); persister.Add(t2); var t = persister.GetAll(); foreach (var timeoutData in t) { using (var tx = new TransactionScope()) { persister.Remove(timeoutData.Id); tx.Complete(); } } t = persister.GetAll(); Assert.AreEqual(0, t.Count()); }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { using (var session = SessionFactory.OpenSession()) using (var tx = session.BeginTransaction(IsolationLevel.ReadCommitted)) { var te = session.Get <TimeoutEntity>(new Guid(timeoutId)); if (te == null) { timeoutData = null; return(false); } timeoutData = new TimeoutData { CorrelationId = te.CorrelationId, Destination = te.Destination, Id = te.Id.ToString(), SagaId = te.SagaId, State = te.State, Time = te.Time, Headers = ConvertStringToDictionary(te.Headers), }; session.Delete(te); tx.Commit(); return(true); } }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { var query = Builders <TimeoutEntity> .Filter.Eq(t => t.Id, timeoutId); var entity = _collection.Find(query).FirstOrDefault(); if (entity == null) { timeoutData = null; return(false); } timeoutData = new TimeoutData { Destination = entity.Destination, Id = entity.Id, SagaId = entity.SagaId, State = entity.State, Time = entity.Time, Headers = entity.Headers, }; if (_collection.DeleteOne(query).DeletedCount == 0) { timeoutData = null; return(false); } return(true); }
public void Should_return_the_correct_headers() { var headers = new Dictionary <string, string> { { "Bar", "34234" }, { "Foo", "aString1" }, { "Super", "aString2" } }; var timeout = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), Destination = new Address("timeouts", RuntimeEnvironment.MachineName), SagaId = Guid.NewGuid(), State = new byte[] { 1, 1, 133, 200 }, Headers = headers, OwningTimeoutManager = "MyTestEndpoint", }; persister.Add(timeout); TimeoutData timeoutData; persister.TryRemove(timeout.Id, out timeoutData); CollectionAssert.AreEqual(headers, timeoutData.Headers); }
public async Task TryRemove_should_work_with_concurrent_transactions() { var timeout = new TimeoutData { Time = DateTime.Now }; await persister.Add(timeout, new ContextBag()).ConfigureAwait(false); var t1EnteredTx = new AutoResetEvent(false); var t2EnteredTx = new AutoResetEvent(false); var task1 = Task.Run(() => { t1EnteredTx.Set(); t2EnteredTx.WaitOne(); return(persister.TryRemove(timeout.Id, new ContextBag())); }); var task2 = Task.Run(() => { t2EnteredTx.Set(); t1EnteredTx.WaitOne(); return(persister.TryRemove(timeout.Id, new ContextBag())); }); var results = await Task.WhenAll(task1, task2).ConfigureAwait(false); Assert.IsTrue(results.Single(x => x)); }
public void Should_remove_timeouts_by_sagaid() { var sagaId1 = Guid.NewGuid(); var sagaId2 = Guid.NewGuid(); var t1 = new TimeoutData { SagaId = sagaId1, Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary <string, string> { { "Header1", "Value1" } } }; var t2 = new TimeoutData { SagaId = sagaId2, Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary <string, string> { { "Header1", "Value1" } } }; persister.Add(t1); persister.Add(t2); persister.RemoveTimeoutBy(sagaId1); persister.RemoveTimeoutBy(sagaId2); using (var session = sessionFactory.OpenSession()) { Assert.Null(session.Get <TimeoutEntity>(new Guid(t1.Id))); Assert.Null(session.Get <TimeoutEntity>(new Guid(t2.Id))); } }
public void Peek_should_return_timeout_with_id() { var timeoutData = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), Destination = new Address("timeouts", RuntimeEnvironment.MachineName), SagaId = Guid.NewGuid(), State = new byte[] { 0, 0, 133 }, Headers = new Dictionary <string, string> { { "Bar", "34234" }, { "Foo", "aString1" }, { "Super", "aString2" } }, OwningTimeoutManager = "MyTestEndpoint" }; persister.Add(timeoutData); var result = persister.Peek(timeoutData.Id); Assert.AreEqual(timeoutData.Id, result.Id); Assert.AreEqual(timeoutData.Time.ToString("G"), result.Time.ToString("G")); Assert.AreEqual(timeoutData.Destination, result.Destination); Assert.AreEqual(timeoutData.SagaId, result.SagaId); Assert.AreEqual(timeoutData.State, result.State); Assert.AreEqual(timeoutData.Headers, result.Headers); }
public void Add(TimeoutData timeout) { lock (storage) { timeout.Id = Guid.NewGuid().ToString(); storage.Add(timeout); } }
public void Remove(TimeoutData timeout) { using (var session = OpenSession()) { session.Advanced.Defer(new DeleteCommandData { Key = timeout.Id }); session.SaveChanges(); } }
public void Add(TimeoutData timeout) { using (var session = OpenSession()) { session.Store(timeout); session.SaveChanges(); } }
public async Task Invoke(MessageContext context) { var sagaId = Guid.Empty; string sagaIdString; if (context.Headers.TryGetValue(Headers.SagaId, out sagaIdString)) { sagaId = Guid.Parse(sagaIdString); } if (context.Headers.ContainsKey(TimeoutManagerHeaders.ClearTimeouts)) { if (sagaId == Guid.Empty) { throw new InvalidOperationException("Invalid saga id specified, clear timeouts is only supported for saga instances"); } await persister.RemoveTimeoutBy(sagaId, context.Context).ConfigureAwait(false); } else { string expire; if (!context.Headers.TryGetValue(TimeoutManagerHeaders.Expire, out expire)) { throw new InvalidOperationException("Non timeout message arrived at the timeout manager, id:" + context.MessageId); } var destination = GetReplyToAddress(context); string routeExpiredTimeoutTo; if (context.Headers.TryGetValue(TimeoutManagerHeaders.RouteExpiredTimeoutTo, out routeExpiredTimeoutTo)) { destination = routeExpiredTimeoutTo; } var data = new TimeoutData { Destination = destination, SagaId = sagaId, State = context.Body, Time = DateTimeExtensions.ToUtcDateTime(expire), Headers = context.Headers, OwningTimeoutManager = owningTimeoutManager }; if (data.Time.AddSeconds(-1) <= DateTime.UtcNow) { var outgoingMessage = new OutgoingMessage(context.MessageId, data.Headers, data.State); var transportOperation = new TransportOperation(outgoingMessage, new UnicastAddressTag(data.Destination)); await dispatcher.Dispatch(new TransportOperations(transportOperation), context.TransportTransaction, context.Context).ConfigureAwait(false); return; } await persister.Add(data, context.Context).ConfigureAwait(false); poller.NewTimeoutRegistered(data.Time); } }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { lock (lockObject) { timeoutData = storage.SingleOrDefault(t => t.Id == timeoutId); return timeoutData != null && storage.Remove(timeoutData); } }
public void Add(TimeoutData timeout) { var context = new ServiceContext(account.CreateCloudTableClient()){ IgnoreResourceNotFoundException = true}; string identifier; timeout.Headers.TryGetValue(Headers.MessageId, out identifier); if (string.IsNullOrEmpty(identifier)) { identifier = Hash(timeout); } TimeoutDataEntity timeoutDataEntity; if (TryGetTimeoutData(context, identifier, string.Empty, out timeoutDataEntity)) return; var stateAddress = Upload(timeout.State, identifier); var headers = Serialize(timeout.Headers); if (!TryGetTimeoutData(context, timeout.Time.ToString(PartitionKeyScope), stateAddress, out timeoutDataEntity)) context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(timeout.Time.ToString(PartitionKeyScope), stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); timeout.Id = stateAddress; if (timeout.SagaId != default(Guid) && !TryGetTimeoutData(context, timeout.SagaId.ToString(), stateAddress, out timeoutDataEntity)) context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(timeout.SagaId.ToString(), stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(stateAddress, string.Empty) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); context.SaveChanges(); }
public void Add(TimeoutData timeout) { var context = new ServiceContext(account.CreateCloudTableClient()); var hash = Hash(timeout); TimeoutDataEntity timeoutDataEntity; if (TryGetTimeoutData(context, hash, string.Empty, out timeoutDataEntity)) return; var stateAddress = Upload(timeout.State, hash); var headers = Serialize(timeout.Headers); if (!TryGetTimeoutData(context, timeout.Time.ToString(PartitionKeyScope), stateAddress, out timeoutDataEntity)) context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(timeout.Time.ToString(PartitionKeyScope), stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); timeout.Id = stateAddress; if (timeout.SagaId != default(Guid) && !TryGetTimeoutData(context, timeout.SagaId.ToString(), stateAddress, out timeoutDataEntity)) context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(timeout.SagaId.ToString(), stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); context.AddObject(ServiceContext.TimeoutDataTableName, new TimeoutDataEntity(stateAddress, string.Empty) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId, OwningTimeoutManager = timeout.OwningTimeoutManager, Headers = headers }); context.SaveChanges(); }
public bool CanSend(TimeoutData data) { var hash = Hash(data); TimeoutDataEntity timeoutDataEntity; if (!TryGetTimeoutData(hash, out timeoutDataEntity)) return false; var leaseBlob = container.GetBlockBlobReference(timeoutDataEntity.StateAddress); using (var lease = new AutoRenewLease(leaseBlob)) { return lease.HasLease; } }
public void Add(TimeoutData timeout) { timeout.Id = Guid.NewGuid().ToString(); try { readerWriterLock.EnterWriteLock(); storage.Add(timeout); } finally { readerWriterLock.ExitWriteLock(); } }
void IPersistTimeouts.Add(TimeoutData timeout) { var stateAddress = Serialize(timeout.State, Hash(timeout)); context.AttachTo(ServiceContext.TimeoutDataEntityTableName, new TimeoutDataEntity("TimeoutData", stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time }); context.SaveChanges(SaveChangesOptions.ReplaceOnUpdate); }
public void Should_return_the_correct_headers() { var headers = new Dictionary<string, string> { { "Bar", "34234" }, { "Foo", "dasdsa" }, { "Super", "dsfsdf" } }; var timeout = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), CorrelationId = "boo", Destination = new Address("timeouts", Environment.MachineName), SagaId = Guid.NewGuid(), State = new byte[] {1, 1, 133, 200}, Headers = headers, OwningTimeoutManager = Configure.EndpointName, }; persister.Add(timeout); TimeoutData timeoutData; persister.TryRemove(timeout.Id, out timeoutData); CollectionAssert.AreEqual(headers, timeoutData.Headers); }
public Task Add(TimeoutData timeout, ContextBag context) { timeout.Id = Guid.NewGuid().ToString(); try { readerWriterLock.EnterWriteLock(); storage.Add(timeout); } finally { readerWriterLock.ExitWriteLock(); } return TaskEx.CompletedTask; }
void IPersistTimeouts.Add(TimeoutData timeout) { var stateAddress = Serialize(timeout.State, Hash(timeout)); context.AddObject(ServiceContext.TimeoutDataEntityTableName, new TimeoutDataEntity("TimeoutData", stateAddress) { Destination = timeout.Destination.ToString(), SagaId = timeout.SagaId, StateAddress = stateAddress, Time = timeout.Time, CorrelationId = timeout.CorrelationId }); context.SaveChanges(); }
public bool CanSend(TimeoutData data) { var hash = Hash(data); var result = (from c in context.TimeoutData where c.RowKey == hash select c).SingleOrDefault(); if (result == null) return false; var leaseBlob = container.GetBlockBlobReference(result.StateAddress); using (var lease = new AutoRenewLease(leaseBlob)) { return lease.HasLease; } }
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); }
/// <summary> /// Adds a new timeout. /// </summary> /// <param name="timeout">Timeout data.</param> public void Add(TimeoutData timeout) { var timeoutId = GenerateCombGuid(); IDbConnection connection; if (TryGetConnection(out connection)) { StoreTimeoutEntity(timeout, connection, timeoutId); } else { using (connection = SessionFactory.GetConnection()) { StoreTimeoutEntity(timeout, connection, timeoutId); } } timeout.Id = timeoutId.ToString(); }
public void Should_remove_timeouts_by_sagaid() { var sagaId1 = Guid.NewGuid(); var sagaId2 = Guid.NewGuid(); var t1 = new TimeoutData { SagaId = sagaId1, Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary<string, string> { { "Header1", "Value1" } } }; var t2 = new TimeoutData { SagaId = sagaId2, Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary<string, string> { { "Header1", "Value1" } } }; persister.Add(t1); persister.Add(t2); persister.RemoveTimeoutBy(sagaId1); persister.RemoveTimeoutBy(sagaId2); using (var session = sessionFactory.OpenSession()) { Assert.Null(session.Get<TimeoutEntity>(new Guid(t1.Id))); Assert.Null(session.Get<TimeoutEntity>(new Guid(t2.Id))); } }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData { Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary<string, string> { { "Header1", "Value1" } } }; var t2 = new TimeoutData { Time = DateTime.Now.AddYears(1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary<string, string> { { "Header1", "Value1" } } }; persister.Add(t1); persister.Add(t2); var t = persister.GetAll(); foreach (var timeoutData in t) { persister.Remove(timeoutData.Id); } using (var session = sessionFactory.OpenSession()) { Assert.Null(session.Get<TimeoutEntity>(new Guid(t1.Id))); Assert.Null(session.Get<TimeoutEntity>(new Guid(t2.Id))); } }
public void Peek_should_return_timeout_with_id() { var timeoutData = new TimeoutData { Time = DateTime.UtcNow.AddHours(-1), Destination = new Address("timeouts", RuntimeEnvironment.MachineName), SagaId = Guid.NewGuid(), State = new byte[] { 0, 0, 133 }, Headers = new Dictionary<string, string> { { "Bar", "34234" }, { "Foo", "aString1" }, { "Super", "aString2" } }, OwningTimeoutManager = "MyTestEndpoint" }; persister.Add(timeoutData); var result = persister.Peek(timeoutData.Id); Assert.AreEqual(timeoutData.Id, result.Id); Assert.AreEqual(timeoutData.Time.ToString("G"), result.Time.ToString("G")); Assert.AreEqual(timeoutData.Destination, result.Destination); Assert.AreEqual(timeoutData.SagaId, result.SagaId); Assert.AreEqual(timeoutData.State, result.State); Assert.AreEqual(timeoutData.Headers, result.Headers); }
public void Should_remove_timeouts_by_id() { var t1 = new TimeoutData { Time = DateTime.Now.AddYears(-1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary<string, string> { {"Header1", "Value1"} } }; var t2 = new TimeoutData { Time = DateTime.Now.AddYears(-1), OwningTimeoutManager = Configure.EndpointName, Headers = new Dictionary<string, string> { {"Header1", "Value1"} } }; persister.Add(t1); persister.Add(t2); DateTime nextTimeToRunQuery; var timeouts = persister.GetNextChunk(DateTime.UtcNow.AddYears(-3), out nextTimeToRunQuery); foreach (var timeout in timeouts) { TimeoutData timeoutData; persister.TryRemove(timeout.Item1, out timeoutData); } using (var session = sessionFactory.OpenSession()) { Assert.Null(session.Get<TimeoutEntity>(new Guid(t1.Id))); Assert.Null(session.Get<TimeoutEntity>(new Guid(t2.Id))); } }
public void Add(TimeoutData timeout) { var newId = Guid.NewGuid(); using (var session = SessionFactory.OpenSession()) using (var tx = session.BeginTransaction(IsolationLevel.ReadCommitted)) { session.Save(new TimeoutEntity { Id = newId, CorrelationId = timeout.CorrelationId, Destination = timeout.Destination, SagaId = timeout.SagaId, State = timeout.State, Time = timeout.Time, Headers = ConvertDictionaryToString(timeout.Headers), Endpoint = timeout.OwningTimeoutManager, }); tx.Commit(); } timeout.Id = newId.ToString(); }
public bool TryRemove(string timeoutId, out TimeoutData timeoutData) { try { bool result = false; timeoutData = null; readerWriterLock.EnterWriteLock(); using (ITransaction tx = _context.StateManager.CreateTransaction()) { var storage = storages.GetOrAddAsync(tx, EndpointName, type => new List<TimeoutData>()).Result; for (var index = 0; index < storage.Count; index++) { var data = storage[index]; if (data.Id == timeoutId) { timeoutData = data; storage.RemoveAt(index); result = true; break; } } storages.AddOrUpdateAsync(tx, EndpointName, type => new List<TimeoutData>(), (t, o) => storage).Wait(); tx.CommitAsync().Wait(); } return result; } catch (Exception ex) { throw ex; } finally { readerWriterLock.ExitWriteLock(); } }
private static string Hash(TimeoutData timeout) { var s = timeout.SagaId + timeout.Destination.ToString() + timeout.Time.Ticks; var sha1 = SHA1.Create(); var bytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(s)); var hash = new StringBuilder(); for (var i = 0; i < bytes.Length; i++) { hash.Append(bytes[i].ToString("X2")); } return hash.ToString(); }
private void TimeoutsManagerOnTimeoutPushed(object sender, TimeoutData timeoutData) { lock (lockObject) { if (nextRetrieval > timeoutData.Time) { nextRetrieval = timeoutData.Time; } timeoutPushed = true; } }