From 5ec1b8a939fbd3d3e2221e11153832bd4559f40a Mon Sep 17 00:00:00 2001 From: Luca Domenichini Date: Wed, 10 Jan 2024 11:11:31 +0100 Subject: [PATCH 1/2] FIX missing Dispose of cts --- .../SmartIOT.Connector.Tcp/Client/TcpClientConnector.cs | 8 +++++--- .../SmartIOT.Connector.Tcp/Server/TcpServerConnector.cs | 2 ++ .../Connector/AbstractBufferedAggregatingConnector.cs | 1 + Tests/SmartIOT.Connector.Tcp.Tests/TcpConnectorTests.cs | 2 ++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Connectors/SmartIOT.Connector.Tcp/Client/TcpClientConnector.cs b/Connectors/SmartIOT.Connector.Tcp/Client/TcpClientConnector.cs index 7ef5be6..7fcce1f 100644 --- a/Connectors/SmartIOT.Connector.Tcp/Client/TcpClientConnector.cs +++ b/Connectors/SmartIOT.Connector.Tcp/Client/TcpClientConnector.cs @@ -14,7 +14,7 @@ public class TcpClientConnector : AbstractPublisherConnector private TcpClient? _tcpClient; private readonly IStreamMessageSerializer _messageSerializer; private readonly CancellationTokenSource _stopToken = new CancellationTokenSource(); - private readonly ManualResetEventSlim _reconnectTaskTerminated = new ManualResetEventSlim(); + private readonly SemaphoreSlim _reconnectTaskTerminated = new SemaphoreSlim(0, 1); private readonly CountdownLatch _clients = new CountdownLatch(); public TcpClientConnector(TcpClientConnectorOptions options) @@ -167,7 +167,7 @@ await connectorInterface.RunInitializationActionAsync(async (deviceStatusEvents, } finally { - _reconnectTaskTerminated.Set(); + _reconnectTaskTerminated.Release(); } }); } @@ -266,6 +266,8 @@ public override async Task StopAsync() _tcpClient?.Close(); _clients.WaitUntilZero(); - _reconnectTaskTerminated.Wait(); + await _reconnectTaskTerminated.WaitAsync(); + + _stopToken.Dispose(); } } diff --git a/Connectors/SmartIOT.Connector.Tcp/Server/TcpServerConnector.cs b/Connectors/SmartIOT.Connector.Tcp/Server/TcpServerConnector.cs index 5779514..eb9152c 100644 --- a/Connectors/SmartIOT.Connector.Tcp/Server/TcpServerConnector.cs +++ b/Connectors/SmartIOT.Connector.Tcp/Server/TcpServerConnector.cs @@ -217,5 +217,7 @@ public override async Task StopAsync() { client.Close(); } + + _stopToken.Dispose(); } } diff --git a/Core/SmartIOT.Connector.Core/Connector/AbstractBufferedAggregatingConnector.cs b/Core/SmartIOT.Connector.Core/Connector/AbstractBufferedAggregatingConnector.cs index 101ca29..d218303 100644 --- a/Core/SmartIOT.Connector.Core/Connector/AbstractBufferedAggregatingConnector.cs +++ b/Core/SmartIOT.Connector.Core/Connector/AbstractBufferedAggregatingConnector.cs @@ -79,6 +79,7 @@ public override Task StartAsync(ISmartIOTConnectorInterface connectorInterface) public override Task StopAsync() { _stopToken.Cancel(); + _stopToken.Dispose(); ConnectorInterface!.OnConnectorStopped(new ConnectorStoppedEventArgs(this, $"Connector stopped {ConnectionString}")); diff --git a/Tests/SmartIOT.Connector.Tcp.Tests/TcpConnectorTests.cs b/Tests/SmartIOT.Connector.Tcp.Tests/TcpConnectorTests.cs index bb50aef..92870e6 100644 --- a/Tests/SmartIOT.Connector.Tcp.Tests/TcpConnectorTests.cs +++ b/Tests/SmartIOT.Connector.Tcp.Tests/TcpConnectorTests.cs @@ -175,6 +175,7 @@ public async Task Test_scheduler_and_TcpClientConnector(string serializerType, i await connector.StopAsync(); token?.Cancel(); + token?.Dispose(); stream?.Close(); server.Stop(); } @@ -337,6 +338,7 @@ public async Task Test_scheduler_and_TcpServerConnector(string serializerType, i await connector.StopAsync(); token?.Cancel(); + token?.Dispose(); stream?.Close(); client.Close(); } From b2a6014732f990b3d1d288174e6c28da53c05cc0 Mon Sep 17 00:00:00 2001 From: Luca Domenichini Date: Wed, 10 Jan 2024 11:40:07 +0100 Subject: [PATCH 2/2] FIX disabled devices should not try to initialize --- .../Scheduler/TagSchedulerEngine.cs | 3 ++ .../TagSchedulerEngineTests.cs | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Core/SmartIOT.Connector.Core/Scheduler/TagSchedulerEngine.cs b/Core/SmartIOT.Connector.Core/Scheduler/TagSchedulerEngine.cs index b74bde1..55283bc 100644 --- a/Core/SmartIOT.Connector.Core/Scheduler/TagSchedulerEngine.cs +++ b/Core/SmartIOT.Connector.Core/Scheduler/TagSchedulerEngine.cs @@ -524,6 +524,9 @@ private void OnTagWrite(TagScheduleEvent evt) public bool IsRestartNeeded() { + if (DeviceDriver.Device.DeviceStatus == DeviceStatus.DISABLED) + return false; + bool restart = _lastRestartInstant == null; if (!restart && _timeService.IsTimeoutElapsed(_lastRestartInstant!.Value, _configuration.RestartDeviceInErrorTimeout)) diff --git a/Tests/SmartIOT.Connector.Core.Tests/TagSchedulerEngineTests.cs b/Tests/SmartIOT.Connector.Core.Tests/TagSchedulerEngineTests.cs index a7905d5..15a818c 100644 --- a/Tests/SmartIOT.Connector.Core.Tests/TagSchedulerEngineTests.cs +++ b/Tests/SmartIOT.Connector.Core.Tests/TagSchedulerEngineTests.cs @@ -37,6 +37,41 @@ private static (TagSchedulerEngine engine, Model.Device device, Tag tag20, Tag? return (engine, device, device.Tags.First(x => x.TagId == "DB20")!, device.Tags.FirstOrDefault(x => x.TagId == "DB21"), device.Tags.First(x => x.TagId == "DB22")!); } + [Fact] + public void Test_should_not_restart_on_disabled_device() + { + var timeService = new FakeTimeService + { + Now = DateTime.Now + }; + + SchedulerConfiguration schedulerConfiguration = new SchedulerConfiguration(); + + (TagSchedulerEngine engine, Model.Device device, Tag tag20, Tag? tag21, Tag tag22) = SetupSystem(device => new MockDeviceDriver(device), timeService, schedulerConfiguration, true, false, 0); + device.SetEnabled(false); // disable device + + var eventListener = new FakeConnector(); + + engine.TagReadEvent += eventListener.OnTagReadEvent; + engine.TagWriteEvent += eventListener.OnTagWriteEvent; + engine.DeviceStatusEvent += eventListener.OnDeviceStatusEvent; + engine.ExceptionHandler += eventListener.OnException; + + // verifica stato iniziale + Assert.Equal(DeviceStatus.DISABLED, device.DeviceStatus); + Assert.False(tag20.IsInitialized); + Assert.Equal(0, tag20.ErrorCode); + Assert.False(tag21!.IsInitialized); + Assert.Equal(0, tag21.ErrorCode); + Assert.False(tag22.IsInitialized); + Assert.Equal(0, tag22.ErrorCode); + + // check driver restart + Assert.False(engine.IsRestartNeeded()); + + Assert.Throws(() => engine.GetNextTagSchedule()); + } + [Fact] public void Test_read_two_tags_cycle() {