Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
<configuration>
<packageSources>
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
<add key="xunit" value="https://www.myget.org/F/xunit/api/v3/index.json" />
</packageSources>
</configuration>
128 changes: 128 additions & 0 deletions src/NetMQ/Monitoring/INetMQMonitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using System;
using System.Threading.Tasks;

namespace NetMQ.Monitoring
{
/// <summary>
/// Monitors a <see cref="NetMQSocket"/> for events, raising them via events.
/// </summary>
/// <remarks>
/// To run a monitor instance, either:
/// <list type="bullet">
/// <item>Call <see cref="Start"/> (blocking) and <see cref="Stop"/>, or</item>
/// <item>Call <see cref="AttachToPoller{T}"/> and <see cref="DetachFromPoller()"/>.</item>
/// </list>
/// </remarks>
public interface INetMQMonitor : IDisposable
{
/// <summary>
/// Gets the monitoring address.
/// </summary>
string Endpoint { get; }

/// <summary>
/// Gets whether this monitor is currently running.
/// </summary>
/// <remarks>
/// Start the monitor running via either <see cref="Start"/> or <see cref="AttachToPoller{T}"/>.
/// Stop the monitor via either <see cref="Stop"/> or <see cref="DetachFromPoller()"/>.
/// </remarks>
bool IsRunning { get; }

/// <summary>
/// Gets and sets the timeout interval for poll iterations when using <see cref="Start"/> and <see cref="Stop"/>.
/// </summary>
/// <remarks>
/// The higher the number the longer it may take the to stop the monitor.
/// This value has no effect when the monitor is run via <see cref="AttachToPoller{T}"/>.
/// </remarks>
TimeSpan Timeout { get; set; }

/// <summary>
/// Raised whenever any monitored event fires.
/// </summary>
event EventHandler<NetMQMonitorEventArgs>? EventReceived;

/// <summary>
/// Occurs when a connection is made to a socket.
/// </summary>
event EventHandler<NetMQMonitorSocketEventArgs>? Connected;

/// <summary>
/// Occurs when a synchronous connection attempt failed, and its completion is being polled for.
/// </summary>
event EventHandler<NetMQMonitorErrorEventArgs>? ConnectDelayed;

/// <summary>
/// Occurs when an asynchronous connect / reconnection attempt is being handled by a reconnect timer.
/// </summary>
event EventHandler<NetMQMonitorIntervalEventArgs>? ConnectRetried;

/// <summary>
/// Occurs when a socket is bound to an address and is ready to accept connections.
/// </summary>
event EventHandler<NetMQMonitorSocketEventArgs>? Listening;

/// <summary>
/// Occurs when a socket could not bind to an address.
/// </summary>
event EventHandler<NetMQMonitorErrorEventArgs>? BindFailed;

/// <summary>
/// Occurs when a connection from a remote peer has been established with a socket's listen address.
/// </summary>
event EventHandler<NetMQMonitorSocketEventArgs>? Accepted;

/// <summary>
/// Occurs when a connection attempt to a socket's bound address fails.
/// </summary>
event EventHandler<NetMQMonitorErrorEventArgs>? AcceptFailed;

/// <summary>
/// Occurs when a connection was closed.
/// </summary>
event EventHandler<NetMQMonitorSocketEventArgs>? Closed;

/// <summary>
/// Occurs when a connection couldn't be closed.
/// </summary>
event EventHandler<NetMQMonitorErrorEventArgs>? CloseFailed;

/// <summary>
/// Occurs when the stream engine (TCP and IPC specific) detects a corrupted / broken session.
/// </summary>
event EventHandler<NetMQMonitorSocketEventArgs>? Disconnected;

/// <summary>
/// Adds the monitor object to a NetMQPoller. Register to <see cref="EventReceived"/> to be signalled on new events.
/// </summary>
/// <param name="poller">The poller to attach to.</param>
/// <typeparam name="T">The type of poller.</typeparam>
/// <exception cref="ArgumentNullException">The <paramref name="poller"/> is <c>null</c>.</exception>
/// <exception cref="InvalidOperationException">The monitor is already started or already attached to a poller.</exception>
void AttachToPoller<T>(T poller) where T : INetMQPoller;

/// <summary>
/// Removes the monitor object from the attached poller.
/// </summary>
void DetachFromPoller();

/// <summary>
/// Starts monitoring the socket. This method doesn't start a new thread and will block until the monitor poll is stopped.
/// </summary>
/// <exception cref="InvalidOperationException">The Monitor must not have already started nor attached to a poller.</exception>
void Start();

/// <summary>
/// Starts a background task for the monitoring operation.
/// </summary>
/// <returns>A task representing the monitoring operation.</returns>
Task StartAsync();

/// <summary>
/// Stops monitoring. Blocks until monitoring completed.
/// </summary>
/// <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>
void Stop();
}
}
104 changes: 21 additions & 83 deletions src/NetMQ/Monitoring/NetMQMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,8 @@

namespace NetMQ.Monitoring
{
/// <summary>
/// Monitors a <see cref="NetMQSocket"/> for events, raising them via events.
/// </summary>
/// <remarks>
/// To run a monitor instance, either:
/// <list type="bullet">
/// <item>Call <see cref="Start"/> (blocking) and <see cref="Stop"/>, or</item>
/// <item>Call <see cref="AttachToPoller{T}"/> and <see cref="DetachFromPoller()"/>.</item>
/// </list>
/// </remarks>
public class NetMQMonitor : IDisposable
/// <inheritdoc />
public class NetMQMonitor : INetMQMonitor
{
private readonly NetMQSocket m_monitoringSocket;
private readonly bool m_ownsMonitoringSocket;
Expand Down Expand Up @@ -68,84 +59,48 @@ public NetMQMonitor(NetMQSocket socket, string endpoint, bool ownsSocket = false
m_ownsMonitoringSocket = ownsSocket;
}

/// <summary>
/// The monitoring address.
/// </summary>
/// <inheritdoc />
public string Endpoint { get; }

/// <summary>
/// Get whether this monitor is currently running.
/// </summary>
/// <remarks>
/// Start the monitor running via either <see cref="Start"/> or <see cref="AttachToPoller{T}"/>.
/// Stop the monitor via either <see cref="Stop"/> or <see cref="DetachFromPoller()"/>.
/// </remarks>
/// <inheritdoc />
public bool IsRunning { get; private set; }

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

#region Events

/// <summary>
/// Raised whenever any monitored event fires.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorEventArgs>? EventReceived;

/// <summary>
/// Occurs when a connection is made to a socket.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorSocketEventArgs>? Connected;

/// <summary>
/// Occurs when a synchronous connection attempt failed, and its completion is being polled for.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorErrorEventArgs>? ConnectDelayed;

/// <summary>
/// Occurs when an asynchronous connect / reconnection attempt is being handled by a reconnect timer.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorIntervalEventArgs>? ConnectRetried;

/// <summary>
/// Occurs when a socket is bound to an address and is ready to accept connections.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorSocketEventArgs>? Listening;

/// <summary>
/// Occurs when a socket could not bind to an address.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorErrorEventArgs>? BindFailed;

/// <summary>
/// Occurs when a connection from a remote peer has been established with a socket's listen address.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorSocketEventArgs>? Accepted;

/// <summary>
/// Occurs when a connection attempt to a socket's bound address fails.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorErrorEventArgs>? AcceptFailed;

/// <summary>
/// Occurs when a connection was closed.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorSocketEventArgs>? Closed;

/// <summary>
/// Occurs when a connection couldn't be closed.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorErrorEventArgs>? CloseFailed;

/// <summary>
/// Occurs when the stream engine (TCP and IPC specific) detects a corrupted / broken session.
/// </summary>
/// <inheritdoc />
public event EventHandler<NetMQMonitorSocketEventArgs>? Disconnected;

#endregion
Expand Down Expand Up @@ -219,13 +174,7 @@ private void InternalClose()
}
}

/// <summary>
/// Add the monitor object to a NetMQPoller, register to <see cref="EventReceived"/> to be signalled on new events
/// </summary>
/// <param name="poller"></param>
/// <typeparam name="T"></typeparam>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="InvalidOperationException"></exception>
/// <inheritdoc />
public void AttachToPoller<T>(T poller) where T : INetMQPoller
{
if (poller == null)
Expand All @@ -239,9 +188,7 @@ public void AttachToPoller<T>(T poller) where T : INetMQPoller
poller.Add(m_monitoringSocket);
}

/// <summary>
/// Remove the monitor object from attached poller
/// </summary>
/// <inheritdoc />
public void DetachFromPoller()
{
DetachFromPoller(false);
Expand All @@ -260,10 +207,7 @@ private void DetachFromPoller(bool dispose)
InternalClose();
}

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

/// <summary>
/// Start a background task for the monitoring operation.
/// </summary>
/// <returns></returns>
/// <inheritdoc />
public Task StartAsync()
{
if (IsRunning)
Expand All @@ -302,10 +243,7 @@ public Task StartAsync()
return Task.Factory.StartNew(Start);
}

/// <summary>
/// Stop monitoring. Blocks until monitoring completed.
/// </summary>
/// <exception cref="InvalidOperationException">If this monitor is attached to a poller you must detach it first and not use the stop method.</exception>
/// <inheritdoc />
public void Stop()
{
if (m_attachedPoller != null)
Expand Down