Skip to content

CORE-18630 Add state manager for outbound sessions #5438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

YashNabar
Copy link
Contributor

@YashNabar YashNabar commented Jan 15, 2024

Add state manager transitions to the stateful session manager for outbound sessions. Introduce caching for established sessions.
Note: This feature is disabled in this change.

…er-for-inbound-sessions' into yash/outbound-sessions

 Conflicts:
	components/link-manager/src/main/kotlin/net/corda/p2p/linkmanager/sessions/StatefulSessionManagerImpl.kt
(sessionsNotInCache.map { it.first } - inboundSessionsFromStateManager.map { it.first }.toSet()).map {
getSessionIdFilter(getSessionId(it))
}
val outboundSessionsFromStateManager: List<Pair<T, SessionManager.SessionDirection>> =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused; where in the state API we asked for only inbound or outbound?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inbound and outbound sessions are keyed differently, so to retrieve inbound sessions (keyed by session ID) we simply do a stateManager.get(), but for outbound sessions we query based on metadata with stateManager.findByMetadataMatchingAny().

That said, if we're happy to have a common metadata type for inbound and outbound (as I have here), we could query for both types of sessions with stateManager.findByMetadataMatchingAny()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that stateManager.findByMetadataMatchingAny() is order O(N) where N is the size of the table as stateManager.get() is O(1). So I think we should avoid stateManager.findByMetadataMatchingAny() where possible (as we need to lookup outbound sessions by sessionId sometimes we can't always avoid this).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we key both by session ID (maybe add input/output before hand?)

@corda-jenkins-ci02
Copy link
Contributor

corda-jenkins-ci02 bot commented Jan 16, 2024

Jenkins build for PR 5438 build 16

Build Successful:
Jar artifact version produced by this PR: 5.2.0.0-alpha-1706115052476
Helm chart version produced by this PR: 5.2.0-alpha.1706115052476
Helm chart pushed to: oci://corda-os-docker-dev.software.r3.com/helm-charts/pr-5438/corda

}

SessionStatus.SentInitiatorHello, SessionStatus.SentInitiatorHandshake -> {
state.replaySessionMessage()?.let {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think returning NewSessionNeeded here can be a bit misleading, since that was supposed to be used when a session doesn't exist at all, while here it exists and we just need to replay.

I understand why you probably did it, just to comply with the logic in the outbound message processor which otherwise won't send these messages. But, there are a few options that might keep the codebase a bit easier to understand:

  • we could also have a publisher in this component and publish the message here instead of relying on the outbound message processor (we don't require any atomic semantics). That way, we could still return SessionAlreadyPending which I think will be slightly cleaner. The downside is if we do that before we try and update the state manager, there's still a chance we'll replay from multiple link managers.
  • we could introduce an extra field in SessionAlreadyPending for messages that need to be sent by upstream clients. Then, we can include the messages that the outbound message processor needs to send there. That way, we can process the result of the state manager updates and filter out messages in cases where updates failed because another link manager managed to write first (so that we replay only once).

Note: This is more of a cleanliness thing I think, since functionally what you have could work. So, you could do that as a follow-up cleanup if you want.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could rename NewSessionNeeded to SendSessionNegotiationMessage (one button in InteliJ so we can do this quickly now).

Not sure what the second option would do to the layer above (would the logic become the same for SessionAlreadyPending and NewSessionNeeded ). Not sure I like adding the complexity of adding an extra publisher (first option).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the second option, it would probably be an extra field in SessionAlreadyPending with messages to send optionally & a piece of logic / conditional on the outbound processor that would check in that case whether there are messages to send if a session is already pending.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I raise a follow up ticket to do this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, if the other people agree, we can raise a follow-up ticket to refactor this a bit.

}

SessionStatus.SentInitiatorHello, SessionStatus.SentInitiatorHandshake -> {
state.replaySessionMessage()?.let {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could rename NewSessionNeeded to SendSessionNegotiationMessage (one button in InteliJ so we can do this quickly now).

Not sure what the second option would do to the layer above (would the logic become the same for SessionAlreadyPending and NewSessionNeeded ). Not sure I like adding the complexity of adding an extra publisher (first option).

YashNabar and others added 15 commits January 18, 2024 15:42
…er-for-inbound-sessions' into yash/outbound-sessions/CORE-18630

 Conflicts:
	components/link-manager/src/main/kotlin/net/corda/p2p/linkmanager/common/CommonComponents.kt
	components/link-manager/src/main/kotlin/net/corda/p2p/linkmanager/sessions/SessionManagerImpl.kt
	components/link-manager/src/main/kotlin/net/corda/p2p/linkmanager/sessions/StatefulSessionManagerImpl.kt
	components/link-manager/src/main/kotlin/net/corda/p2p/linkmanager/sessions/metadata/InboundSessionMetadata.kt
…/enable-e2e-tests-over-yash

# Conflicts:
#	components/link-manager/src/main/kotlin/net/corda/p2p/linkmanager/sessions/StatefulSessionManagerImpl.kt
@YashNabar YashNabar changed the title CORE-18630 Add state manager for outbound sessions (WIP) CORE-18630 Add state manager for outbound sessions Jan 24, 2024
Copy link

Quality Gate Passed Quality Gate passed

Kudos, no new issues were introduced!

0 New issues
0 Security Hotspots
No data about Coverage
0.1% Duplication on New Code

See analysis details on SonarCloud

Copy link
Contributor

@williamvigorr3 williamvigorr3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@YashNabar YashNabar marked this pull request as ready for review January 25, 2024 09:28
@YashNabar YashNabar requested review from a team as code owners January 25, 2024 09:28
@YashNabar YashNabar merged commit 88b86b2 into WillV/CORE-18631-add-state-manager-for-inbound-sessions Jan 25, 2024
@YashNabar YashNabar deleted the yash/outbound-sessions/CORE-18630 branch January 25, 2024 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants