Skip to content

Commit b368be3

Browse files
Copilotdrewnoakes
andauthored
Add INetMQMonitor interface to enable mocking in tests (#1138)
Add INetMQMonitor interface and update NetMQMonitor to implement it Co-authored-by: drewnoakes <[email protected]>
1 parent 1ab9ad0 commit b368be3

File tree

3 files changed

+149
-90
lines changed

3 files changed

+149
-90
lines changed

NuGet.Config

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace NetMQ.Monitoring
5+
{
6+
/// <summary>
7+
/// Monitors a <see cref="NetMQSocket"/> for events, raising them via events.
8+
/// </summary>
9+
/// <remarks>
10+
/// To run a monitor instance, either:
11+
/// <list type="bullet">
12+
/// <item>Call <see cref="Start"/> (blocking) and <see cref="Stop"/>, or</item>
13+
/// <item>Call <see cref="AttachToPoller{T}"/> and <see cref="DetachFromPoller()"/>.</item>
14+
/// </list>
15+
/// </remarks>
16+
public interface INetMQMonitor : IDisposable
17+
{
18+
/// <summary>
19+
/// Gets the monitoring address.
20+
/// </summary>
21+
string Endpoint { get; }
22+
23+
/// <summary>
24+
/// Gets whether this monitor is currently running.
25+
/// </summary>
26+
/// <remarks>
27+
/// Start the monitor running via either <see cref="Start"/> or <see cref="AttachToPoller{T}"/>.
28+
/// Stop the monitor via either <see cref="Stop"/> or <see cref="DetachFromPoller()"/>.
29+
/// </remarks>
30+
bool IsRunning { get; }
31+
32+
/// <summary>
33+
/// Gets and sets the timeout interval for poll iterations when using <see cref="Start"/> and <see cref="Stop"/>.
34+
/// </summary>
35+
/// <remarks>
36+
/// The higher the number the longer it may take the to stop the monitor.
37+
/// This value has no effect when the monitor is run via <see cref="AttachToPoller{T}"/>.
38+
/// </remarks>
39+
TimeSpan Timeout { get; set; }
40+
41+
/// <summary>
42+
/// Raised whenever any monitored event fires.
43+
/// </summary>
44+
event EventHandler<NetMQMonitorEventArgs>? EventReceived;
45+
46+
/// <summary>
47+
/// Occurs when a connection is made to a socket.
48+
/// </summary>
49+
event EventHandler<NetMQMonitorSocketEventArgs>? Connected;
50+
51+
/// <summary>
52+
/// Occurs when a synchronous connection attempt failed, and its completion is being polled for.
53+
/// </summary>
54+
event EventHandler<NetMQMonitorErrorEventArgs>? ConnectDelayed;
55+
56+
/// <summary>
57+
/// Occurs when an asynchronous connect / reconnection attempt is being handled by a reconnect timer.
58+
/// </summary>
59+
event EventHandler<NetMQMonitorIntervalEventArgs>? ConnectRetried;
60+
61+
/// <summary>
62+
/// Occurs when a socket is bound to an address and is ready to accept connections.
63+
/// </summary>
64+
event EventHandler<NetMQMonitorSocketEventArgs>? Listening;
65+
66+
/// <summary>
67+
/// Occurs when a socket could not bind to an address.
68+
/// </summary>
69+
event EventHandler<NetMQMonitorErrorEventArgs>? BindFailed;
70+
71+
/// <summary>
72+
/// Occurs when a connection from a remote peer has been established with a socket's listen address.
73+
/// </summary>
74+
event EventHandler<NetMQMonitorSocketEventArgs>? Accepted;
75+
76+
/// <summary>
77+
/// Occurs when a connection attempt to a socket's bound address fails.
78+
/// </summary>
79+
event EventHandler<NetMQMonitorErrorEventArgs>? AcceptFailed;
80+
81+
/// <summary>
82+
/// Occurs when a connection was closed.
83+
/// </summary>
84+
event EventHandler<NetMQMonitorSocketEventArgs>? Closed;
85+
86+
/// <summary>
87+
/// Occurs when a connection couldn't be closed.
88+
/// </summary>
89+
event EventHandler<NetMQMonitorErrorEventArgs>? CloseFailed;
90+
91+
/// <summary>
92+
/// Occurs when the stream engine (TCP and IPC specific) detects a corrupted / broken session.
93+
/// </summary>
94+
event EventHandler<NetMQMonitorSocketEventArgs>? Disconnected;
95+
96+
/// <summary>
97+
/// Adds the monitor object to a NetMQPoller. Register to <see cref="EventReceived"/> to be signalled on new events.
98+
/// </summary>
99+
/// <param name="poller">The poller to attach to.</param>
100+
/// <typeparam name="T">The type of poller.</typeparam>
101+
/// <exception cref="ArgumentNullException">The <paramref name="poller"/> is <c>null</c>.</exception>
102+
/// <exception cref="InvalidOperationException">The monitor is already started or already attached to a poller.</exception>
103+
void AttachToPoller<T>(T poller) where T : INetMQPoller;
104+
105+
/// <summary>
106+
/// Removes the monitor object from the attached poller.
107+
/// </summary>
108+
void DetachFromPoller();
109+
110+
/// <summary>
111+
/// Starts monitoring the socket. This method doesn't start a new thread and will block until the monitor poll is stopped.
112+
/// </summary>
113+
/// <exception cref="InvalidOperationException">The Monitor must not have already started nor attached to a poller.</exception>
114+
void Start();
115+
116+
/// <summary>
117+
/// Starts a background task for the monitoring operation.
118+
/// </summary>
119+
/// <returns>A task representing the monitoring operation.</returns>
120+
Task StartAsync();
121+
122+
/// <summary>
123+
/// Stops monitoring. Blocks until monitoring completed.
124+
/// </summary>
125+
/// <exception cref="InvalidOperationException">If this monitor is attached to a poller you must detach it first and not use the <see cref="Stop"/> method.</exception>
126+
void Stop();
127+
}
128+
}

src/NetMQ/Monitoring/NetMQMonitor.cs

Lines changed: 21 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,8 @@
77

88
namespace NetMQ.Monitoring
99
{
10-
/// <summary>
11-
/// Monitors a <see cref="NetMQSocket"/> for events, raising them via events.
12-
/// </summary>
13-
/// <remarks>
14-
/// To run a monitor instance, either:
15-
/// <list type="bullet">
16-
/// <item>Call <see cref="Start"/> (blocking) and <see cref="Stop"/>, or</item>
17-
/// <item>Call <see cref="AttachToPoller{T}"/> and <see cref="DetachFromPoller()"/>.</item>
18-
/// </list>
19-
/// </remarks>
20-
public class NetMQMonitor : IDisposable
10+
/// <inheritdoc />
11+
public class NetMQMonitor : INetMQMonitor
2112
{
2213
private readonly NetMQSocket m_monitoringSocket;
2314
private readonly bool m_ownsMonitoringSocket;
@@ -68,84 +59,48 @@ public NetMQMonitor(NetMQSocket socket, string endpoint, bool ownsSocket = false
6859
m_ownsMonitoringSocket = ownsSocket;
6960
}
7061

71-
/// <summary>
72-
/// The monitoring address.
73-
/// </summary>
62+
/// <inheritdoc />
7463
public string Endpoint { get; }
7564

76-
/// <summary>
77-
/// Get whether this monitor is currently running.
78-
/// </summary>
79-
/// <remarks>
80-
/// Start the monitor running via either <see cref="Start"/> or <see cref="AttachToPoller{T}"/>.
81-
/// Stop the monitor via either <see cref="Stop"/> or <see cref="DetachFromPoller()"/>.
82-
/// </remarks>
65+
/// <inheritdoc />
8366
public bool IsRunning { get; private set; }
8467

85-
/// <summary>
86-
/// Gets and sets the timeout interval for poll iterations when using <see cref="Start"/> and <see cref="Stop"/>.
87-
/// </summary>
88-
/// <remarks>
89-
/// The higher the number the longer it may take the to stop the monitor.
90-
/// This value has no effect when the monitor is run via <see cref="AttachToPoller{T}"/>.
91-
/// </remarks>
68+
/// <inheritdoc />
9269
public TimeSpan Timeout { get; set; }
9370

9471
#region Events
9572

96-
/// <summary>
97-
/// Raised whenever any monitored event fires.
98-
/// </summary>
73+
/// <inheritdoc />
9974
public event EventHandler<NetMQMonitorEventArgs>? EventReceived;
10075

101-
/// <summary>
102-
/// Occurs when a connection is made to a socket.
103-
/// </summary>
76+
/// <inheritdoc />
10477
public event EventHandler<NetMQMonitorSocketEventArgs>? Connected;
10578

106-
/// <summary>
107-
/// Occurs when a synchronous connection attempt failed, and its completion is being polled for.
108-
/// </summary>
79+
/// <inheritdoc />
10980
public event EventHandler<NetMQMonitorErrorEventArgs>? ConnectDelayed;
11081

111-
/// <summary>
112-
/// Occurs when an asynchronous connect / reconnection attempt is being handled by a reconnect timer.
113-
/// </summary>
82+
/// <inheritdoc />
11483
public event EventHandler<NetMQMonitorIntervalEventArgs>? ConnectRetried;
11584

116-
/// <summary>
117-
/// Occurs when a socket is bound to an address and is ready to accept connections.
118-
/// </summary>
85+
/// <inheritdoc />
11986
public event EventHandler<NetMQMonitorSocketEventArgs>? Listening;
12087

121-
/// <summary>
122-
/// Occurs when a socket could not bind to an address.
123-
/// </summary>
88+
/// <inheritdoc />
12489
public event EventHandler<NetMQMonitorErrorEventArgs>? BindFailed;
12590

126-
/// <summary>
127-
/// Occurs when a connection from a remote peer has been established with a socket's listen address.
128-
/// </summary>
91+
/// <inheritdoc />
12992
public event EventHandler<NetMQMonitorSocketEventArgs>? Accepted;
13093

131-
/// <summary>
132-
/// Occurs when a connection attempt to a socket's bound address fails.
133-
/// </summary>
94+
/// <inheritdoc />
13495
public event EventHandler<NetMQMonitorErrorEventArgs>? AcceptFailed;
13596

136-
/// <summary>
137-
/// Occurs when a connection was closed.
138-
/// </summary>
97+
/// <inheritdoc />
13998
public event EventHandler<NetMQMonitorSocketEventArgs>? Closed;
14099

141-
/// <summary>
142-
/// Occurs when a connection couldn't be closed.
143-
/// </summary>
100+
/// <inheritdoc />
144101
public event EventHandler<NetMQMonitorErrorEventArgs>? CloseFailed;
145102

146-
/// <summary>
147-
/// Occurs when the stream engine (TCP and IPC specific) detects a corrupted / broken session.
148-
/// </summary>
103+
/// <inheritdoc />
149104
public event EventHandler<NetMQMonitorSocketEventArgs>? Disconnected;
150105

151106
#endregion
@@ -219,13 +174,7 @@ private void InternalClose()
219174
}
220175
}
221176

222-
/// <summary>
223-
/// Add the monitor object to a NetMQPoller, register to <see cref="EventReceived"/> to be signalled on new events
224-
/// </summary>
225-
/// <param name="poller"></param>
226-
/// <typeparam name="T"></typeparam>
227-
/// <exception cref="ArgumentNullException"></exception>
228-
/// <exception cref="InvalidOperationException"></exception>
177+
/// <inheritdoc />
229178
public void AttachToPoller<T>(T poller) where T : INetMQPoller
230179
{
231180
if (poller == null)
@@ -239,9 +188,7 @@ public void AttachToPoller<T>(T poller) where T : INetMQPoller
239188
poller.Add(m_monitoringSocket);
240189
}
241190

242-
/// <summary>
243-
/// Remove the monitor object from attached poller
244-
/// </summary>
191+
/// <inheritdoc />
245192
public void DetachFromPoller()
246193
{
247194
DetachFromPoller(false);
@@ -260,10 +207,7 @@ private void DetachFromPoller(bool dispose)
260207
InternalClose();
261208
}
262209

263-
/// <summary>
264-
/// Start monitor the socket, the method doesn't start a new thread and will block until the monitor poll is stopped
265-
/// </summary>
266-
/// <exception cref="InvalidOperationException">The Monitor must not have already started nor attached to a poller.</exception>
210+
/// <inheritdoc />
267211
public void Start()
268212
{
269213
if (IsRunning)
@@ -287,10 +231,7 @@ public void Start()
287231
}
288232
}
289233

290-
/// <summary>
291-
/// Start a background task for the monitoring operation.
292-
/// </summary>
293-
/// <returns></returns>
234+
/// <inheritdoc />
294235
public Task StartAsync()
295236
{
296237
if (IsRunning)
@@ -302,10 +243,7 @@ public Task StartAsync()
302243
return Task.Factory.StartNew(Start);
303244
}
304245

305-
/// <summary>
306-
/// Stop monitoring. Blocks until monitoring completed.
307-
/// </summary>
308-
/// <exception cref="InvalidOperationException">If this monitor is attached to a poller you must detach it first and not use the stop method.</exception>
246+
/// <inheritdoc />
309247
public void Stop()
310248
{
311249
if (m_attachedPoller != null)

0 commit comments

Comments
 (0)