Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
mregen committed Aug 5, 2024
2 parents 9b4ecf6 + e7ae573 commit f5992a2
Show file tree
Hide file tree
Showing 19 changed files with 180 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.Expressions" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.Expressions" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
Expand Down
2 changes: 1 addition & 1 deletion Fuzzing/Encoders/Fuzz.Tools/Encoders.Fuzz.Tools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<PackageReference Include="SharpFuzz" Version="2.1.1" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.Expressions" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
Expand Down
5 changes: 5 additions & 0 deletions Libraries/Opc.Ua.Client/Session/ISession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ public interface ISession : ISessionClient
/// </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>
Expand Down
81 changes: 66 additions & 15 deletions Libraries/Opc.Ua.Client/Session/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public partial class Session : SessionClientBatched, ISession
{
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;
Expand Down Expand Up @@ -238,6 +239,7 @@ private void Initialize()
m_keepAliveInterval = 5000;
m_tooManyPublishRequests = 0;
m_minPublishRequestCount = kDefaultPublishRequestCount;
m_maxPublishRequestCount = kMaxPublishRequestCountMax;
m_sessionName = "";
m_deleteSubscriptionsOnClose = true;
m_transferSubscriptionsOnReconnect = false;
Expand Down Expand Up @@ -828,6 +830,29 @@ public int MinPublishRequestCount
}
}
}

/// <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
Expand Down Expand Up @@ -4950,12 +4975,7 @@ public IAsyncResult BeginPublish(int timeout)
/// </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)
Expand Down Expand Up @@ -5245,15 +5265,16 @@ public bool ResendData(IEnumerable<Subscription> subscriptions, out IList<Servic
private void QueueBeginPublish()
{
int requestCount = GoodPublishRequestCount;
int minPublishRequestCount = GetMinPublishRequestCount(false);

int minPublishRequestCount = GetDesiredPublishRequestCount(false);

if (requestCount < minPublishRequestCount)
{
BeginPublish(OperationTimeout);
}
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);
}
}

Expand Down Expand Up @@ -5540,8 +5561,8 @@ private void ValidateServerEndpoints(EndpointDescriptionCollection serverEndpoin
/// <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,
Expand Down Expand Up @@ -5892,7 +5913,7 @@ private void ProcessPublishResponse(
}
}

// 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)
Expand Down Expand Up @@ -6236,12 +6257,14 @@ private bool BelowPublishRequestLimit(int requestCount)
}

/// <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)
{
Expand All @@ -6250,6 +6273,8 @@ private int GetMinPublishRequestCount(bool createdOnly)
return 0;
}

int publishCount;

if (createdOnly)
{
int count = 0;
Expand All @@ -6265,11 +6290,36 @@ private int GetMinPublishRequestCount(bool createdOnly)
{
return 0;
}
publishCount = count;
}
else
{
publishCount = m_subscriptions.Count;
}

return Math.Max(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;
}

return Math.Max(m_subscriptions.Count, m_minPublishRequestCount);
//
// 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;
}
}

Expand Down Expand Up @@ -6517,6 +6567,7 @@ protected virtual void ProcessResponseAdditionalHeader(ResponseHeader responseHe
private bool m_reconnecting;
private SemaphoreSlim m_reconnectLock;
private int m_minPublishRequestCount;
private int m_maxPublishRequestCount;
private LinkedList<AsyncRequestState> m_outstandingRequests;
private string m_userTokenSecurityPolicyUri;
#if ECC_SUPPORT
Expand Down
7 changes: 7 additions & 0 deletions Libraries/Opc.Ua.Client/Session/TraceableSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,13 @@ public int MinPublishRequestCount
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;

Expand Down
28 changes: 2 additions & 26 deletions Libraries/Opc.Ua.Client/Subscription/Subscription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,7 @@ public Subscription(Subscription template, bool copyEventHandlers)

if (template != null)
{
string displayName = template.DisplayName;

if (String.IsNullOrEmpty(displayName))
{
displayName = m_displayName;
}

// remove any existing numeric suffix.
int index = displayName.LastIndexOf(' ');

if (index != -1)
{
try
{
displayName = displayName.Substring(0, index);
}
catch
{
// not a numeric suffix.
}
}

m_displayName = Utils.Format("{0} {1}", displayName, Utils.IncrementIdentifier(ref s_globalSubscriptionCounter));
m_displayName = template.m_displayName;
m_publishingInterval = template.m_publishingInterval;
m_keepAliveCount = template.m_keepAliveCount;
m_lifetimeCount = template.m_lifetimeCount;
Expand Down Expand Up @@ -1850,7 +1828,7 @@ private void StartKeepAliveTimer()
if (m_keepAliveInterval < kMinKeepAliveTimerInterval)
{
m_keepAliveInterval = (int)(Math.Min(m_publishingInterval * (m_keepAliveCount + 1), Int32.MaxValue));
m_keepAliveInterval = Math.Min(kMinKeepAliveTimerInterval, m_keepAliveInterval);
m_keepAliveInterval = Math.Max(kMinKeepAliveTimerInterval, m_keepAliveInterval);
}
#if NET6_0_OR_GREATER
var publishTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(m_keepAliveInterval));
Expand Down Expand Up @@ -2850,8 +2828,6 @@ private class IncomingMessage
}

private LinkedList<IncomingMessage> m_incomingMessages;

private static long s_globalSubscriptionCounter;
#endregion
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,5 @@ private bool InternalAddPolicy(ServerSecurityPolicyCollection policies, MessageS
#region Private Fields
private bool m_typeSelected;
#endregion

}
}
Loading

0 comments on commit f5992a2

Please sign in to comment.