Skip to content

Commit 8aa57eb

Browse files
authored
Merge pull request #938 from mmillerbe/master
NetMQMonitor Can Throw "Unnecessarily"
2 parents dc15b2d + 3f4a1ec commit 8aa57eb

File tree

4 files changed

+53
-14
lines changed

4 files changed

+53
-14
lines changed

src/NetMQ.Tests/NetMQMonitorTests.cs

+28
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Linq;
33
using System.Threading;
44
using System.Threading.Tasks;
5+
using AsyncIO;
6+
using NetMQ.Core;
57
using NetMQ.Monitoring;
68
using NetMQ.Sockets;
79
using Xunit;
@@ -157,5 +159,31 @@ public void MonitorDisposeProperlyWhenDisposedAfterMonitoredTcpSocket()
157159
}
158160
// NOTE If this test fails, it will hang because context.Dispose will block
159161
}
162+
163+
[Fact]
164+
public void ConvertArgDoesNotThrowForNullSocket()
165+
{
166+
AsyncSocket? socket = null;
167+
MonitorEvent monitorEvent = new MonitorEvent(SocketEvents.All, addr: "", arg: socket!);
168+
Assert.Null(monitorEvent.ConvertArg<AsyncSocket>());
169+
}
170+
171+
[Fact]
172+
public void ConvertArgDoesNotThrowForNonNullSocket()
173+
{
174+
using (AsyncSocket socket = AsyncSocket.CreateIPv4Tcp())
175+
{
176+
MonitorEvent monitorEvent = new MonitorEvent(SocketEvents.All, addr: "", arg: socket);
177+
Assert.Equal(socket, monitorEvent.ConvertArg<AsyncSocket>());
178+
}
179+
}
180+
181+
[Fact]
182+
public void ConvertArgThrowsForInvalidType()
183+
{
184+
AsyncSocket? socket = null;
185+
MonitorEvent monitorEvent = new MonitorEvent(SocketEvents.All, addr: "", arg: socket!);
186+
Assert.Throws<ArgumentException>(() => monitorEvent.ConvertArg<int>());
187+
}
160188
}
161189
}

src/NetMQ/Core/MonitorEvent.cs

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using System.Runtime.InteropServices;
34
using AsyncIO;
45
using NetMQ.Core.Transports;
@@ -159,5 +160,17 @@ public static MonitorEvent Read(SocketBase s)
159160

160161
return new MonitorEvent(@event, addr, arg);
161162
}
163+
164+
[return: MaybeNull]
165+
public T ConvertArg<T>()
166+
{
167+
if (Arg is T v)
168+
return v;
169+
170+
if (Arg is null && default(T) is null)
171+
return default;
172+
173+
throw new ArgumentException($"Command argument must be of type {typeof(T).Name}.");
174+
}
162175
}
163176
}

src/NetMQ/Monitoring/NetMQMonitor.cs

+10-12
Original file line numberDiff line numberDiff line change
@@ -156,39 +156,37 @@ private void Handle(object sender, NetMQSocketEventArgs socketEventArgs)
156156
{
157157
var monitorEvent = MonitorEvent.Read(m_monitoringSocket.SocketHandle);
158158

159-
T GetArg<T>() => monitorEvent.Arg is T v ? v : throw new ArgumentException($"Command argument must be of type {typeof(T).Name}.");
160-
161159
switch (monitorEvent.Event)
162160
{
163161
case SocketEvents.Connected:
164-
InvokeEvent(Connected, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, GetArg<AsyncSocket>(), SocketEvents.Connected));
162+
InvokeEvent(Connected, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, monitorEvent.ConvertArg<AsyncSocket>(), SocketEvents.Connected));
165163
break;
166164
case SocketEvents.ConnectDelayed:
167-
InvokeEvent(ConnectDelayed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)GetArg<int>(), SocketEvents.ConnectDelayed));
165+
InvokeEvent(ConnectDelayed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)monitorEvent.ConvertArg<int>(), SocketEvents.ConnectDelayed));
168166
break;
169167
case SocketEvents.ConnectRetried:
170-
InvokeEvent(ConnectRetried, new NetMQMonitorIntervalEventArgs(this, monitorEvent.Addr, GetArg<int>(), SocketEvents.ConnectRetried));
168+
InvokeEvent(ConnectRetried, new NetMQMonitorIntervalEventArgs(this, monitorEvent.Addr, monitorEvent.ConvertArg<int>(), SocketEvents.ConnectRetried));
171169
break;
172170
case SocketEvents.Listening:
173-
InvokeEvent(Listening, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, GetArg<AsyncSocket>(), SocketEvents.Listening));
171+
InvokeEvent(Listening, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, monitorEvent.ConvertArg<AsyncSocket>(), SocketEvents.Listening));
174172
break;
175173
case SocketEvents.BindFailed:
176-
InvokeEvent(BindFailed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)GetArg<int>(), SocketEvents.BindFailed));
174+
InvokeEvent(BindFailed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)monitorEvent.ConvertArg<int>(), SocketEvents.BindFailed));
177175
break;
178176
case SocketEvents.Accepted:
179-
InvokeEvent(Accepted, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, GetArg<AsyncSocket>(), SocketEvents.Accepted));
177+
InvokeEvent(Accepted, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, monitorEvent.ConvertArg<AsyncSocket>(), SocketEvents.Accepted));
180178
break;
181179
case SocketEvents.AcceptFailed:
182-
InvokeEvent(AcceptFailed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)GetArg<int>(), SocketEvents.AcceptFailed));
180+
InvokeEvent(AcceptFailed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)monitorEvent.ConvertArg<int>(), SocketEvents.AcceptFailed));
183181
break;
184182
case SocketEvents.Closed:
185-
InvokeEvent(Closed, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, GetArg<AsyncSocket>(), SocketEvents.Closed));
183+
InvokeEvent(Closed, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, monitorEvent.ConvertArg<AsyncSocket>(), SocketEvents.Closed));
186184
break;
187185
case SocketEvents.CloseFailed:
188-
InvokeEvent(CloseFailed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)GetArg<int>(), SocketEvents.CloseFailed));
186+
InvokeEvent(CloseFailed, new NetMQMonitorErrorEventArgs(this, monitorEvent.Addr, (ErrorCode)monitorEvent.ConvertArg<int>(), SocketEvents.CloseFailed));
189187
break;
190188
case SocketEvents.Disconnected:
191-
InvokeEvent(Disconnected, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, GetArg<AsyncSocket>(), SocketEvents.Disconnected));
189+
InvokeEvent(Disconnected, new NetMQMonitorSocketEventArgs(this, monitorEvent.Addr, monitorEvent.ConvertArg<AsyncSocket>(), SocketEvents.Disconnected));
192190
break;
193191
default:
194192
throw new Exception("unknown event " + monitorEvent.Event);

src/NetMQ/Monitoring/NetMQMonitorEventArgs.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class NetMQMonitorSocketEventArgs : NetMQMonitorEventArgs
4949
/// <param name="address">The address of the event.</param>
5050
/// <param name="socketEvent">The type of socket event that occurred.</param>
5151
/// <param name="socket">The socket upon which this event occurred.</param>
52-
public NetMQMonitorSocketEventArgs(NetMQMonitor monitor, string address, AsyncSocket socket, SocketEvents socketEvent)
52+
public NetMQMonitorSocketEventArgs(NetMQMonitor monitor, string address, AsyncSocket? socket, SocketEvents socketEvent)
5353
: base(monitor, address, socketEvent)
5454
{
5555
Socket = socket;
@@ -58,7 +58,7 @@ public NetMQMonitorSocketEventArgs(NetMQMonitor monitor, string address, AsyncSo
5858
/// <summary>
5959
/// Gets the socket upon which this event occurred.
6060
/// </summary>
61-
public AsyncSocket Socket { get; }
61+
public AsyncSocket? Socket { get; }
6262
}
6363

6464
/// <summary>

0 commit comments

Comments
 (0)