public void disconnected_client_has_assigned_streams_sent_to_another_client() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; var sub = new Core.Services.PersistentSubscription.PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent()); reader.Load(null); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-1", client1Envelope, 10, "foo", "bar"); var client2Id = Guid.NewGuid(); sub.AddClient(Guid.NewGuid(), client2Id, "connection-2", client2Envelope, 10, "foo", "bar"); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 0, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-1", 0), false)); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 1, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-2", 0), false)); Assert.AreEqual(1, client1Envelope.Replies.Count); Assert.AreEqual(1, client2Envelope.Replies.Count); sub.RemoveClientByConnectionId(client2Id); // Message 2 should be retried on client 1 as it wasn't acked. Assert.AreEqual(2, client1Envelope.Replies.Count); Assert.AreEqual(1, client2Envelope.Replies.Count); }
public void events_are_skipped_if_assigned_client_full() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; var sub = new Core.Services.PersistentSubscription.PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent()); reader.Load(null); var correlationId = Guid.NewGuid(); sub.AddClient(correlationId, Guid.NewGuid(), "connection-1", client1Envelope, 1, "foo", "bar"); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-2", client2Envelope, 1, "foo", "bar"); var message1 = Guid.NewGuid(); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(message1, subsctiptionStream, 0, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-1", 0), false)); Assert.That(client1Envelope.Replies.Count, Is.EqualTo(1)); Assert.That(client2Envelope.Replies.Count, Is.EqualTo(0)); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 1, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-1", 0), false)); Assert.That(client1Envelope.Replies.Count, Is.EqualTo(1)); Assert.That(client2Envelope.Replies.Count, Is.EqualTo(0)); Assert.True(sub.TryGetStreamBuffer(out var streamBuffer)); Assert.That(streamBuffer.BufferCount, Is.EqualTo(1)); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 2, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-2", 0), false)); Assert.That(client1Envelope.Replies.Count, Is.EqualTo(1)); Assert.That(client2Envelope.Replies.Count, Is.EqualTo(1)); Assert.That(streamBuffer.BufferCount, Is.EqualTo(1)); sub.AcknowledgeMessagesProcessed(correlationId, new[] { message1 }); Assert.That(client1Envelope.Replies.Count, Is.EqualTo(2)); Assert.That(client2Envelope.Replies.Count, Is.EqualTo(1)); Assert.That(streamBuffer.BufferCount, Is.EqualTo(0)); }
public void available_capacity_is_tracked_with_acked_messages() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; PersistentSubscriptionParams settings = PersistentSubscriptionToStreamParamsBuilder .CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent(); var consumerStrategy = (PinnedPersistentSubscriptionConsumerStrategy)settings.ConsumerStrategy; var sub = new Core.Services.PersistentSubscription.PersistentSubscription(settings); reader.Load(null); var correlationId1 = Guid.NewGuid(); sub.AddClient(correlationId1, Guid.NewGuid(), "connection-1", client1Envelope, 14, "foo", "bar"); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(14)); var correlationId2 = Guid.NewGuid(); sub.AddClient(correlationId2, Guid.NewGuid(), "connection-2", client2Envelope, 10, "foo", "bar"); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(24)); var message1 = Guid.NewGuid(); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(message1, subsctiptionStream, 0, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-1", 0), false)); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(23)); var message2 = Guid.NewGuid(); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(message2, subsctiptionStream, 1, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-2", 0), false)); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(22)); sub.AcknowledgeMessagesProcessed(correlationId1, new[] { message1 }); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(23)); sub.AcknowledgeMessagesProcessed(correlationId2, new[] { message2 }); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(24)); }
public void live_subscription_with_pinned_by_correlation_pushes_events_with_metadata_with_valid_correlation_to_same_client_for_correlation_id() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); var sub = new PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor("$ce-streamName", "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedByCorrelationPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent()); reader.Load(null); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-1", client1Envelope, 10, "foo", "bar"); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-2", client2Envelope, 10, "foo", "bar"); CorrelationIdPropertyContext.CorrelationIdProperty = "$correlationId2"; var metaData1 = Encoding.UTF8.GetBytes(@"{ ""x"": ""x"", ""$correlationId2"": ""1234567890"", ""y"": ""y"" }"); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-1", 0, metaData1)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-1", 1, metaData1)); Assert.AreEqual(2, client1Envelope.Replies.Count); Assert.AreEqual(0, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-2", 2, metaData1)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-2", 3, metaData1)); Assert.AreEqual(4, client1Envelope.Replies.Count); Assert.AreEqual(0, client2Envelope.Replies.Count); var metaData2 = Encoding.UTF8.GetBytes(@"{ ""$correlationId2"": ""1234567891"", ""y"": ""y"" }"); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-1", 4, metaData2)); Assert.AreEqual(4, client1Envelope.Replies.Count); Assert.AreEqual(1, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-3", 5, metaData2)); Assert.AreEqual(4, client1Envelope.Replies.Count); Assert.AreEqual(2, client2Envelope.Replies.Count); }
live_subscription_with_pinned_by_correlation_pushes_events_to_same_client_for_stream_id_for_metadata(byte[] metaData) { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); var sub = new PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor("$ce-streamName", "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedByCorrelationPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent()); reader.Load(null); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-1", client1Envelope, 10, "foo", "bar"); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-2", client2Envelope, 10, "foo", "bar"); sub.NotifyLiveSubscriptionMessage( Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-1", 0, metaData)); sub.NotifyLiveSubscriptionMessage( Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-1", 1, metaData)); Assert.AreEqual(2, client1Envelope.Replies.Count); Assert.AreEqual(0, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage( Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-2", 2, metaData)); sub.NotifyLiveSubscriptionMessage( Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-2", 3, metaData)); Assert.AreEqual(2, client1Envelope.Replies.Count); Assert.AreEqual(2, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage( Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-1", 4, metaData)); Assert.AreEqual(3, client1Envelope.Replies.Count); Assert.AreEqual(2, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage( Helper.BuildFakeEventWithMetadata(Guid.NewGuid(), "type", "streamName-3", 5, metaData)); Assert.AreEqual(4, client1Envelope.Replies.Count); Assert.AreEqual(2, client2Envelope.Replies.Count); }
public void resolved_link_events_use_event_stream_id() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; var sub = new Core.Services.PersistentSubscription.PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent()); reader.Load(null); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-1", client1Envelope, 10, "foo", "bar"); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-2", client2Envelope, 10, "foo", "bar"); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 0, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-1", 0))); Assert.AreEqual(1, client1Envelope.Replies.Count); Assert.AreEqual(0, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 1, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-2", 0))); Assert.AreEqual(1, client1Envelope.Replies.Count); Assert.AreEqual(1, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 2, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-3", 0))); Assert.AreEqual(2, client1Envelope.Replies.Count); Assert.AreEqual(1, client2Envelope.Replies.Count); sub.NotifyLiveSubscriptionMessage(Helper.BuildLinkEvent(Guid.NewGuid(), subsctiptionStream, 3, Helper.BuildFakeEvent(Guid.NewGuid(), "type", "streamName-4", 0))); Assert.AreEqual(2, client1Envelope.Replies.Count); Assert.AreEqual(2, client2Envelope.Replies.Count); }
public void new_subscription_gets_work() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var client3Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; var sub = new Core.Services.PersistentSubscription.PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new ByLengthHasher())) .StartFromCurrent()); reader.Load(null); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-1", client1Envelope, 10, "foo", "bar"); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-2", client2Envelope, 10, "foo", "bar"); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "1", 0)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "11", 1)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "111", 2)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "1111", 3)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "11111", 4)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "111111", 5)); Assert.AreEqual(3, client1Envelope.Replies.Count); Assert.AreEqual(3, client2Envelope.Replies.Count); sub.AddClient(Guid.NewGuid(), Guid.NewGuid(), "connection-3", client3Envelope, 10, "foo", "bar"); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "1", 6)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "11", 7)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "111", 8)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "1111", 9)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "11111", 10)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "111111", 11)); Assert.AreEqual(5, client1Envelope.Replies.Count); Assert.AreEqual(5, client2Envelope.Replies.Count); Assert.AreEqual(2, client3Envelope.Replies.Count); }
public void available_capacity_is_tracked() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; PersistentSubscriptionParams settings = PersistentSubscriptionToStreamParamsBuilder .CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new XXHashUnsafe())) .StartFromCurrent(); var consumerStrategy = (PinnedPersistentSubscriptionConsumerStrategy)settings.ConsumerStrategy; var sub = new Core.Services.PersistentSubscription.PersistentSubscription(settings); reader.Load(null); var client1Id = Guid.NewGuid(); sub.AddClient(Guid.NewGuid(), client1Id, "connection-1", client1Envelope, 14, "foo", "bar"); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(14)); var client2Id = Guid.NewGuid(); sub.AddClient(Guid.NewGuid(), client2Id, "connection-2", client2Envelope, 10, "foo", "bar"); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(24)); sub.RemoveClientByConnectionId(client2Id); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(14)); sub.RemoveClientByConnectionId(client1Id); Assert.That(consumerStrategy.AvailableCapacity, Is.EqualTo(0)); }
public void bad_availablecapacity_scneanrio_causing_null_reference() { var client1Envelope = new FakeEnvelope(); var client2Envelope = new FakeEnvelope(); var reader = new FakeCheckpointReader(); const string subsctiptionStream = "$ce-streamName"; var sub = new Core.Services.PersistentSubscription.PersistentSubscription( PersistentSubscriptionToStreamParamsBuilder.CreateFor(subsctiptionStream, "groupName") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(reader) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .CustomConsumerStrategy(new PinnedPersistentSubscriptionConsumerStrategy(new ByLengthHasher())) .StartFromCurrent()); reader.Load(null); var conn1Id = Guid.NewGuid(); sub.AddClient(Guid.NewGuid(), conn1Id, "connection-1", client1Envelope, 10, "foo", "bar"); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "1", 0)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "11", 1)); sub.NotifyLiveSubscriptionMessage(Helper.BuildFakeEvent(Guid.NewGuid(), "type", "111", 2)); Assert.AreEqual(3, client1Envelope.Replies.Count); var conn2Id = Guid.NewGuid(); sub.AddClient(Guid.NewGuid(), conn2Id, "connection-2", client2Envelope, 10, "foo", "bar"); Assert.AreEqual(3, client1Envelope.Replies.Count); Assert.AreEqual(0, client2Envelope.Replies.Count); sub.RemoveClientByConnectionId(conn1Id); // Used to throw a null reference exception. Assert.That(() => sub.RemoveClientByConnectionId(conn2Id), Throws.Nothing); }
public void read_batch_size_greater_or_equal_to_buffer_size_throws(int readBatchSize, int bufferSize) { Assert.Throws <ArgumentOutOfRangeException>(() => new Core.Services.PersistentSubscription.PersistentSubscription(PersistentSubscriptionToStreamParamsBuilder .CreateFor("stream", "group") .WithEventLoader(new FakeStreamReader()) .WithCheckpointReader(new FakeCheckpointReader()) .WithCheckpointWriter(new FakeCheckpointWriter(x => { })) .WithMessageParker(new FakeMessageParker()) .StartFromCurrent() .WithReadBatchOf(readBatchSize) .WithHistoryBufferSizeOf(bufferSize))); }