Return due keep-alives from queued publishes#1786
Merged
kevinherron merged 1 commit intoJul 1, 2026
Merged
Conversation
When MaxKeepAliveCount is 1, the row 9 transition to KeepAlive can decrement the keep-alive counter to zero. Return a queued Publish immediately in that case so clients receive the next keep-alive on the expected publishing interval instead of waiting for timeout handling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix a keep-alive timing edge in the server-side Subscription state machine when a client queues multiple Publish requests and the revised
MaxKeepAliveCountis1.OPC UA Part 4 describes Publish requests as a shared session queue: Subscriptions dequeue a Publish request when a NotificationMessage or keep-alive message is ready. The first keep-alive after subscription creation is special, but after that the keep-alive counter controls when the next empty NotificationMessage should be returned. This PR handles the boundary case where Milo transitions from
NORMALintoKEEPALIVE, resets the counter, and immediately decrements it to zero in the same publishing cycle.NORMALtoKEEPALIVEtransition.LATEbehavior when a keep-alive is due but no valid Publish request is queued.1000ms, andMaxKeepAliveCount=1.Key Changes
MaxKeepAliveCount=1, that made the counter due immediately but did not return the queued Publish response on that timer tick.1produces one keep-alive per publishing interval while Publish requests are available.LATEand waits for the next Publish request through the existing late-state path.SubscriptionKeepAliveTestdrives the state machine directly: it queues two Publish requests, advances the publishing timer twice, and verifies the second response completes on the second tick.Testing
SubscriptionKeepAliveTestcovers theMaxKeepAliveCount=1two queued Publish keep-alive sequence.mvn -q -pl opc-ua-sdk/sdk-server -am test -Dtest=SubscriptionKeepAliveTest -Dsurefire.failIfNoSpecifiedTests=falsemvn -q spotless:applymvn -q clean compileLive CTT was not rerun from this branch because the demo server endpoint and CTT project are shared resources controlled by the Standard 2025 train orchestrator.
References