Skip to content

Commit

Permalink
fix edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
romanett committed Oct 10, 2024
1 parent c982aa1 commit 409a51b
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 16 deletions.
30 changes: 18 additions & 12 deletions Libraries/Opc.Ua.Server/Subscription/MonitoredItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,7 @@ public virtual bool Publish(OperationContext context, Queue<EventFieldList> noti
// go to the next sampling interval.
IncrementSampleTime();

bool moreValuesToPublish = false;
// publish events.
if (m_events != null)
{
Expand Down Expand Up @@ -1183,14 +1184,16 @@ public virtual bool Publish(OperationContext context, Queue<EventFieldList> noti
e);
}


int notificationCount = 0;

// place event at the beginning of the queue.
if (overflowEvent != null && m_discardOldest)
{
notifications.Enqueue(overflowEvent);
notificationCount++;
}


int notificationCount = overflowEvent != null ? 1 : 0;
int eventsToRemove = 0;
foreach (EventFieldList fields in m_events)
{
Expand All @@ -1202,11 +1205,7 @@ public virtual bool Publish(OperationContext context, Queue<EventFieldList> noti
// apply any diagnostic masks.
for (int jj = 0; jj < fields.EventFields.Count; jj++)
{
object value = fields.EventFields[jj].Value;

StatusResult result = value as StatusResult;

result?.ApplyDiagnosticMasks(context.DiagnosticsMask, context.StringTable);
(fields.EventFields[jj].Value as StatusResult)?.ApplyDiagnosticMasks(context.DiagnosticsMask, context.StringTable);
}

notifications.Enqueue(fields);
Expand All @@ -1216,17 +1215,24 @@ public virtual bool Publish(OperationContext context, Queue<EventFieldList> noti

m_events.RemoveRange(0, eventsToRemove);

// place event at the end of the queue.
if (overflowEvent != null && !m_discardOldest && !(m_events.Count > 0))
moreValuesToPublish = m_events?.Count > 0;

// place overflow event at the end of the queue if there is still space in the publish.
if (overflowEvent != null && !m_discardOldest)
{
notifications.Enqueue(overflowEvent);
if (notificationCount < maxNotificationsPerPublish)
{
notifications.Enqueue(overflowEvent);
}
else
{
moreValuesToPublish = true;
}
}

Utils.LogTrace(Utils.TraceMasks.OperationDetail, "MONITORED ITEM: Publish(QueueSize={0})", notifications.Count);
}

bool moreValuesToPublish = m_events?.Count > 0;

// reset state variables.
m_overflow = m_overflow && moreValuesToPublish && !m_discardOldest;
m_readyToPublish = moreValuesToPublish;
Expand Down
79 changes: 75 additions & 4 deletions Tests/Opc.Ua.Server.Tests/MonitoredItemTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,74 @@ public void CreateEventMIOverflow()
Assert.That(publishResult.Handle, Is.AssignableTo(typeof(EventQueueOverflowEventState)));
}

[Test]
public void CreateEventMIOverflowMultiplePublish()
{
MonitoredItem monitoredItem = CreateMonitoredItem(true, 2);
Assert.That(monitoredItem, Is.Not.Null);
Assert.That(monitoredItem.ItemsInQueue, Is.EqualTo(0));

monitoredItem.QueueEvent(new AuditUrlMismatchEventState(null));
monitoredItem.QueueEvent(new AuditUrlMismatchEventState(null));

Assert.That(monitoredItem.ItemsInQueue, Is.EqualTo(2));


monitoredItem.QueueEvent(new AuditUrlMismatchEventState(null));

Assert.That(monitoredItem.ItemsInQueue, Is.EqualTo(2));


var result = new Queue<EventFieldList>();
bool moreItems = monitoredItem.Publish(new OperationContext(monitoredItem), result, 2);

Assert.That(moreItems, Is.True);
Assert.That(result, Is.Not.Empty);
Assert.That(result.Count, Is.EqualTo(2));
EventFieldList publishResult = result.LastOrDefault();
Assert.That(publishResult, Is.Not.Null);
Assert.That(publishResult.Handle, Is.AssignableTo(typeof(AuditUrlMismatchEventState)));


var result2 = new Queue<EventFieldList>();
bool moreItems2 = monitoredItem.Publish(new OperationContext(monitoredItem), result2, 2);

Assert.That(moreItems2, Is.False);
Assert.That(result2, Is.Not.Empty);
Assert.That(result2.Count, Is.EqualTo(1));
EventFieldList publishResult2 = result2.FirstOrDefault();
Assert.That(publishResult2, Is.Not.Null);
Assert.That(publishResult2.Handle, Is.AssignableTo(typeof(EventQueueOverflowEventState)));
}

[Test]
public void CreateEventMIOverflowNoDiscard()
{
MonitoredItem monitoredItem = CreateMonitoredItem(true, 2, true);
Assert.That(monitoredItem, Is.Not.Null);
Assert.That(monitoredItem.ItemsInQueue, Is.EqualTo(0));

monitoredItem.QueueEvent(new AuditUrlMismatchEventState(null));
monitoredItem.QueueEvent(new AuditUrlMismatchEventState(null));

Assert.That(monitoredItem.ItemsInQueue, Is.EqualTo(2));


monitoredItem.QueueEvent(new AuditUrlMismatchEventState(null));

Assert.That(monitoredItem.ItemsInQueue, Is.EqualTo(2));


var result = new Queue<EventFieldList>();
monitoredItem.Publish(new OperationContext(monitoredItem), result, 3);

Assert.That(result, Is.Not.Empty);
Assert.That(result.Count, Is.EqualTo(3));
EventFieldList publishResult = result.FirstOrDefault();
Assert.That(publishResult, Is.Not.Null);
Assert.That(publishResult.Handle, Is.AssignableTo(typeof(EventQueueOverflowEventState)));
}


[Test]
public void CreateEventMIPublishPartial()
Expand All @@ -139,17 +207,20 @@ public void CreateEventMIPublishPartial()


var result = new Queue<EventFieldList>();
monitoredItem.Publish(new OperationContext(monitoredItem), result, 2);
bool moreItems = monitoredItem.Publish(new OperationContext(monitoredItem), result, 2);


Assert.That(moreItems, Is.True);
Assert.That(result, Is.Not.Empty);
Assert.That(result.Count, Is.EqualTo(2));
EventFieldList publishResult = result.LastOrDefault();
Assert.That(publishResult, Is.Not.Null);
Assert.That(publishResult.Handle, Is.AssignableTo(typeof(AuditUrlMismatchEventState)));

var result2 = new Queue<EventFieldList>();
monitoredItem.Publish(new OperationContext(monitoredItem), result2, 2);
bool moreItems2 = monitoredItem.Publish(new OperationContext(monitoredItem), result2, 2);

Assert.That(moreItems2, Is.False);
Assert.That(result2, Is.Not.Empty);
Assert.That(result2.Count, Is.EqualTo(1));
EventFieldList publishResult2 = result2.LastOrDefault();
Expand All @@ -159,7 +230,7 @@ public void CreateEventMIPublishPartial()
#endregion

#region private methods
private MonitoredItem CreateMonitoredItem(bool events = false, uint queueSize = 10)
private MonitoredItem CreateMonitoredItem(bool events = false, uint queueSize = 10, bool discardOldest = false)
{
MonitoringFilter filter = events ? new EventFilter() : new MonitoringFilter();

Expand All @@ -185,7 +256,7 @@ private MonitoredItem CreateMonitoredItem(bool events = false, uint queueSize =
null,
1000.0,
queueSize,
false,
discardOldest,
1000
);
}
Expand Down

0 comments on commit 409a51b

Please sign in to comment.