コード例 #1
0
        public async Task DisconnectWhenAConnectIsInProgress()
        {
            // Arrange
            var circuitIdFactory = TestCircuitIdFactory.CreateTestFactory();

            var registry = new TestCircuitRegistry(circuitIdFactory);

            registry.BeforeConnect = new ManualResetEventSlim();
            var circuitHost = TestCircuitHost.Create(circuitIdFactory.CreateCircuitId());

            registry.Register(circuitHost);
            var client = Mock.Of <IClientProxy>();
            var oldId  = circuitHost.Client.ConnectionId;
            var newId  = "new-connection";

            // Act
            var connect    = Task.Run(() => registry.ConnectAsync(circuitHost.CircuitId, client, newId, default));
            var disconnect = Task.Run(() => registry.DisconnectAsync(circuitHost, oldId));

            registry.BeforeConnect.Set();
            await Task.WhenAll(connect, disconnect);

            // Assert
            // We expect the disconnect to fail since the client identifier has changed.
            var actual = Assert.Single(registry.ConnectedCircuits.Values);

            Assert.Same(circuitHost, actual);
            Assert.Same(client, circuitHost.Client.Client);
            Assert.Equal(newId, circuitHost.Client.ConnectionId);

            Assert.False(registry.DisconnectedCircuits.TryGetValue(circuitHost.CircuitId, out _));
        }
コード例 #2
0
        public async Task ReconnectBeforeTimeoutDoesNotGetEntryToBeEvicted()
        {
            // Arrange
            var circuitIdFactory = TestCircuitIdFactory.CreateTestFactory();
            var circuitOptions   = new CircuitOptions
            {
                DisconnectedCircuitRetentionPeriod = TimeSpan.FromSeconds(8),
            };
            var registry = new TestCircuitRegistry(circuitIdFactory, circuitOptions);
            var tcs      = new TaskCompletionSource <object>();

            registry.OnAfterEntryEvicted = () =>
            {
                tcs.TrySetResult(new object());
            };
            var circuitHost = TestCircuitHost.Create(circuitIdFactory.CreateCircuitId());

            registry.RegisterDisconnectedCircuit(circuitHost);
            await registry.ConnectAsync(circuitHost.CircuitId, Mock.Of <IClientProxy>(), "new-connection", default);

            // Act
            await Task.Run(() => tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10)));

            // Verify it's still connected
            Assert.True(registry.ConnectedCircuits.TryGetValue(circuitHost.CircuitId, out var cacheValue));
            Assert.Same(circuitHost, cacheValue);
            // Nothing should be disconnected.
            Assert.False(registry.DisconnectedCircuits.TryGetValue(circuitHost.CircuitId.Secret, out var _));
        }
コード例 #3
0
        public async Task DisconnectedCircuitIsRemovedAfterConfiguredTimeout()
        {
            // Arrange
            var circuitIdFactory = TestCircuitIdFactory.CreateTestFactory();
            var circuitOptions   = new CircuitOptions
            {
                DisconnectedCircuitRetentionPeriod = TimeSpan.FromSeconds(3),
            };
            var registry = new TestCircuitRegistry(circuitIdFactory, circuitOptions);
            var tcs      = new TaskCompletionSource <object>();

            registry.OnAfterEntryEvicted = () =>
            {
                tcs.TrySetResult(new object());
            };
            var circuitHost = TestCircuitHost.Create();

            registry.RegisterDisconnectedCircuit(circuitHost);

            // Act
            // Verify it's present in the dictionary.
            Assert.True(registry.DisconnectedCircuits.TryGetValue(circuitHost.CircuitId.Secret, out var _));
            await Task.Run(() => tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10)));

            Assert.False(registry.DisconnectedCircuits.TryGetValue(circuitHost.CircuitId.Secret, out var _));
        }
コード例 #4
0
        public void CircuitRegistryUsesConfiguredMaxRetainedDisconnectedCircuitsValue()
        {
            // Arrange
            var circuitIdFactory = TestCircuitIdFactory.CreateTestFactory();
            var maxCircuits      = 3;
            var circuitOptions   = new CircuitOptions
            {
                MaxRetainedDisconnectedCircuits = maxCircuits,
            };
            var registry = new TestCircuitRegistry(circuitIdFactory, circuitOptions);
            var hosts    = Enumerable.Range(0, maxCircuits + 2)
                           .Select(_ => TestCircuitHost.Create())
                           .ToArray();

            // Act
            for (var i = 0; i < hosts.Length; i++)
            {
                registry.RegisterDisconnectedCircuit(hosts[i]);
            }

            // Assert
            for (var i = 0; i < maxCircuits; i++)
            {
                Assert.True(registry.DisconnectedCircuits.TryGetValue(hosts[i].CircuitId, out var _));
            }

            // Additional circuits do not get registered.
            Assert.False(registry.DisconnectedCircuits.TryGetValue(hosts[maxCircuits].CircuitId, out var _));
            Assert.False(registry.DisconnectedCircuits.TryGetValue(hosts[maxCircuits + 1].CircuitId, out var _));
        }
コード例 #5
0
        public async Task Connect_WhileDisconnectIsInProgress()
        {
            // Arrange
            var circuitIdFactory = TestCircuitIdFactory.CreateTestFactory();

            var registry = new TestCircuitRegistry(circuitIdFactory);

            registry.BeforeDisconnect = new ManualResetEventSlim();
            var tcs = new TaskCompletionSource <int>();

            var circuitHost = TestCircuitHost.Create(circuitIdFactory.CreateCircuitId());

            registry.Register(circuitHost);
            var client = Mock.Of <IClientProxy>();
            var newId  = "new-connection";

            // Act
            var disconnect = Task.Run(() =>
            {
                var task = registry.DisconnectAsync(circuitHost, circuitHost.Client.ConnectionId);
                tcs.SetResult(0);
                return(task);
            });
            var connect = Task.Run(async() =>
            {
                registry.BeforeDisconnect.Set();
                await tcs.Task;
                await registry.ConnectAsync(circuitHost.CircuitId, client, newId, default);
            });

            registry.BeforeDisconnect.Set();
            await Task.WhenAll(disconnect, connect);

            // Assert
            // We expect the disconnect to finish followed by a reconnect
            var actual = Assert.Single(registry.ConnectedCircuits.Values);

            Assert.Same(circuitHost, actual);
            Assert.Same(client, circuitHost.Client.Client);
            Assert.Equal(newId, circuitHost.Client.ConnectionId);

            Assert.False(registry.DisconnectedCircuits.TryGetValue(circuitHost.CircuitId, out _));
        }
コード例 #6
0
        public async Task Connect_WhileDisconnectIsInProgress_SeriallyExecutesCircuitHandlers()
        {
            // Arrange
            var circuitIdFactory = TestCircuitIdFactory.CreateTestFactory();

            var registry = new TestCircuitRegistry(circuitIdFactory);

            registry.BeforeDisconnect = new ManualResetEventSlim();
            // This verifies that connection up \ down events on a circuit handler are always invoked serially.
            var circuitHandler = new SerialCircuitHandler();
            var tcs            = new TaskCompletionSource <int>();

            var circuitHost = TestCircuitHost.Create(circuitIdFactory.CreateCircuitId(), handlers: new[] { circuitHandler });

            registry.Register(circuitHost);
            var client = Mock.Of <IClientProxy>();
            var newId  = "new-connection";

            // Act
            var disconnect = Task.Run(() =>
            {
                var task = registry.DisconnectAsync(circuitHost, circuitHost.Client.ConnectionId);
                tcs.SetResult(0);
                return(task);
            });
            var connect = Task.Run(async() =>
            {
                registry.BeforeDisconnect.Set();
                await tcs.Task;
                await registry.ConnectAsync(circuitHost.CircuitId, client, newId, default);
            });
            await Task.WhenAll(disconnect, connect);

            // Assert
            Assert.Single(registry.ConnectedCircuits.Values);
            Assert.False(registry.DisconnectedCircuits.TryGetValue(circuitHost.CircuitId, out _));

            Assert.True(circuitHandler.OnConnectionDownExecuted, "OnConnectionDownAsync should have been executed.");
            Assert.True(circuitHandler.OnConnectionUpExecuted, "OnConnectionUpAsync should have been executed.");
        }