mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-29 15:11:53 +08:00
Enhance publish request count management to allow limiting the publish requests to a max count (#2681)
* Enhance publish request count management - Added `MaxPublishRequestCount` property to `ISession` and `Session` in `Opc.Ua.Client`, allowing control over the maximum number of publish requests per session, with validation against predefined constants `kDefaultPublishRequestCount` and `kMaxPublishRequestCountMax` (set to `ushort.MaxValue`). - Introduced `kMaxPublishRequestCountMax` constant in `Session` class for the maximum publish request count limit. - Modified `Session` constructor to initialize `m_maxPublishRequestCount` with `kMaxPublishRequestCountMax`. - Updated `StartPublishing` and `QueueBeginPublish` methods in `Session` to use `GetDesiredPublishRequestCount` for dynamic adjustment of publish requests, considering the session's current state and the new min/max limits. - Added `GetDesiredPublishRequestCount` method in `Session` to calculate the optimal number of active publish requests, ensuring adherence to the newly established limits. - Made minor adjustments and refactoring in `Session` for clarity, consistency, and to support the new publish request count management logic. * Fix build * Lower logging level for debug level message * PR feedback
This commit is contained in:
@@ -277,6 +277,11 @@ namespace Opc.Ua.Client
|
||||
/// </summary>
|
||||
int MinPublishRequestCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the maximum number of publish requests to be used in the session.
|
||||
/// </summary>
|
||||
int MaxPublishRequestCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stores the operation limits of a OPC UA Server.
|
||||
/// </summary>
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace Opc.Ua.Client
|
||||
{
|
||||
private const int kReconnectTimeout = 15000;
|
||||
private const int kMinPublishRequestCountMax = 100;
|
||||
private const int kMaxPublishRequestCountMax = ushort.MaxValue;
|
||||
private const int kDefaultPublishRequestCount = 1;
|
||||
private const int kKeepAliveGuardBand = 1000;
|
||||
private const int kPublishRequestSequenceNumberOutOfOrderThreshold = 10;
|
||||
@@ -286,6 +287,7 @@ namespace Opc.Ua.Client
|
||||
m_keepAliveInterval = 5000;
|
||||
m_tooManyPublishRequests = 0;
|
||||
m_minPublishRequestCount = kDefaultPublishRequestCount;
|
||||
m_maxPublishRequestCount = kMaxPublishRequestCountMax;
|
||||
m_sessionName = "";
|
||||
m_deleteSubscriptionsOnClose = true;
|
||||
m_transferSubscriptionsOnReconnect = false;
|
||||
@@ -876,6 +878,29 @@ namespace Opc.Ua.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the maximum number of publish requests to be used in the session.
|
||||
/// </summary>
|
||||
public int MaxPublishRequestCount
|
||||
{
|
||||
get => Math.Max(m_minPublishRequestCount, m_maxPublishRequestCount);
|
||||
set
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (value >= kDefaultPublishRequestCount && value <= kMaxPublishRequestCountMax)
|
||||
{
|
||||
m_maxPublishRequestCount = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(MaxPublishRequestCount),
|
||||
$"Maximum publish request count must be between {kDefaultPublishRequestCount} and {kMaxPublishRequestCountMax}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Static Methods
|
||||
@@ -4954,12 +4979,7 @@ namespace Opc.Ua.Client
|
||||
/// </summary>
|
||||
public void StartPublishing(int timeout, bool fullQueue)
|
||||
{
|
||||
int publishCount = GetMinPublishRequestCount(true);
|
||||
|
||||
if (m_tooManyPublishRequests > 0 && publishCount > m_tooManyPublishRequests)
|
||||
{
|
||||
publishCount = Math.Max(m_tooManyPublishRequests, m_minPublishRequestCount);
|
||||
}
|
||||
int publishCount = GetDesiredPublishRequestCount(true);
|
||||
|
||||
// refill pipeline. Send at least one publish request if subscriptions are active.
|
||||
if (publishCount > 0 && BeginPublish(timeout) != null)
|
||||
@@ -5249,7 +5269,8 @@ namespace Opc.Ua.Client
|
||||
private void QueueBeginPublish()
|
||||
{
|
||||
int requestCount = GoodPublishRequestCount;
|
||||
int minPublishRequestCount = GetMinPublishRequestCount(false);
|
||||
|
||||
int minPublishRequestCount = GetDesiredPublishRequestCount(false);
|
||||
|
||||
if (requestCount < minPublishRequestCount)
|
||||
{
|
||||
@@ -5257,7 +5278,7 @@ namespace Opc.Ua.Client
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.LogInfo("PUBLISH - Did not send another publish request. GoodPublishRequestCount={0}, MinPublishRequestCount={1}", requestCount, minPublishRequestCount);
|
||||
Utils.LogDebug("PUBLISH - Did not send another publish request. GoodPublishRequestCount={0}, MinPublishRequestCount={1}", requestCount, minPublishRequestCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5544,8 +5565,8 @@ namespace Opc.Ua.Client
|
||||
/// <summary>
|
||||
/// Find and return matching application description
|
||||
/// </summary>
|
||||
/// <param name="endpointDescriptions">The descriptions to search through</param>
|
||||
/// <param name="match">The description to match</param>
|
||||
/// <param name="endpointDescriptions">The descriptions to search through</param>
|
||||
/// <param name="match">The description to match</param>
|
||||
/// <param name="matchPort">Match criteria includes port</param>
|
||||
/// <returns>Matching description or null if no description is matching</returns>
|
||||
private EndpointDescription FindMatchingDescription(EndpointDescriptionCollection endpointDescriptions,
|
||||
@@ -5877,7 +5898,7 @@ namespace Opc.Ua.Client
|
||||
}
|
||||
}
|
||||
|
||||
// Check for outdated sequence numbers. May have been not acked due to a network glitch.
|
||||
// Check for outdated sequence numbers. May have been not acked due to a network glitch.
|
||||
if (latestSequenceNumberToSend != 0 && availableSequenceNumbers?.Count > 0)
|
||||
{
|
||||
foreach (var sequenceNumber in availableSequenceNumbers)
|
||||
@@ -6183,12 +6204,14 @@ namespace Opc.Ua.Client
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the minimum number of active publish request that should be used.
|
||||
/// Returns the desired number of active publish request that should be used.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns 0 if there are no subscriptions.
|
||||
/// </remarks>
|
||||
private int GetMinPublishRequestCount(bool createdOnly)
|
||||
/// <param name="createdOnly">False if call when re-queuing.</param>
|
||||
/// <returns>The number of desired publish requests for the session.</returns>
|
||||
protected virtual int GetDesiredPublishRequestCount(bool createdOnly)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
@@ -6197,6 +6220,8 @@ namespace Opc.Ua.Client
|
||||
return 0;
|
||||
}
|
||||
|
||||
int publishCount;
|
||||
|
||||
if (createdOnly)
|
||||
{
|
||||
int count = 0;
|
||||
@@ -6212,11 +6237,36 @@ namespace Opc.Ua.Client
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.Max(count, m_minPublishRequestCount);
|
||||
publishCount = count;
|
||||
}
|
||||
else
|
||||
{
|
||||
publishCount = m_subscriptions.Count;
|
||||
}
|
||||
|
||||
return Math.Max(m_subscriptions.Count, m_minPublishRequestCount);
|
||||
//
|
||||
// If a dynamic limit was set because of badTooManyPublishRequest error.
|
||||
// limit the number of publish requests to this value.
|
||||
//
|
||||
if (m_tooManyPublishRequests > 0 && publishCount > m_tooManyPublishRequests)
|
||||
{
|
||||
publishCount = m_tooManyPublishRequests;
|
||||
}
|
||||
|
||||
//
|
||||
// Limit resulting to a number between min and max request count.
|
||||
// If max is below min, we honor the min publish request count.
|
||||
// See return from MinPublishRequestCount property which the max of both.
|
||||
//
|
||||
if (publishCount > m_maxPublishRequestCount)
|
||||
{
|
||||
publishCount = m_maxPublishRequestCount;
|
||||
}
|
||||
if (publishCount < m_minPublishRequestCount)
|
||||
{
|
||||
publishCount = m_minPublishRequestCount;
|
||||
}
|
||||
return publishCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6388,6 +6438,7 @@ namespace Opc.Ua.Client
|
||||
private bool m_reconnecting;
|
||||
private SemaphoreSlim m_reconnectLock;
|
||||
private int m_minPublishRequestCount;
|
||||
private int m_maxPublishRequestCount;
|
||||
private LinkedList<AsyncRequestState> m_outstandingRequests;
|
||||
private readonly EndpointDescriptionCollection m_discoveryServerEndpoints;
|
||||
private readonly StringCollection m_discoveryProfileUris;
|
||||
|
||||
@@ -230,6 +230,13 @@ namespace Opc.Ua.Client
|
||||
set => m_session.MinPublishRequestCount = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int MaxPublishRequestCount
|
||||
{
|
||||
get => m_session.MaxPublishRequestCount;
|
||||
set => m_session.MaxPublishRequestCount = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public OperationLimits OperationLimits => m_session.OperationLimits;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user