Skip to content

Conversation

@chesnokoff
Copy link
Contributor

Thank you for submitting the pull request to the Apache Ignite.

In order to streamline the review of the contribution
we ask you to ensure the following steps have been taken:

The Contribution Checklist

  • There is a single JIRA ticket related to the pull request.
  • The web-link to the pull request is attached to the JIRA ticket.
  • The JIRA ticket has the Patch Available state.
  • The pull request body describes changes that have been made.
    The description explains WHAT and WHY was made instead of HOW.
  • The pull request title is treated as the final commit message.
    The following pattern must be used: IGNITE-XXXX Change summary where XXXX - number of JIRA issue.
  • A reviewer has been mentioned through the JIRA comments
    (see the Maintainers list)
  • The pull request has been checked by the Teamcity Bot and
    the green visa attached to the JIRA ticket (see TC.Bot: Check PR)

Notes

If you need any help, please email [email protected] or ask anу advice on http://asf.slack.com #ignite channel.

@chesnokoff chesnokoff force-pushed the ignite-27554 branch 2 times, most recently from 563a5e3 to e7715bc Compare January 16, 2026 14:16
import org.junit.Test;

/** Tests Java serialization header detection in discovery messages. */
public class TcpDiscoveryIoSessionDifferentSerializationTest extends GridCommonAbstractTest {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we introduce a new test like this, let's rename to something like 'TcpDiscoveryDifferentClusterVersionsTest' and fix the javadoc respectively.


TcpDiscoverySpi spi = (TcpDiscoverySpi)grid.configuration().getDiscoverySpi();

TcpDiscoveryHandshakeRequest req = new TcpDiscoveryHandshakeRequest();
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also check the the behaviour with TcpDiscoveryPingRequest / TcpDiscoveryPingResponse. WDYT?

/** */
@Test
public void testDetectJavaObjectStreamHeader() throws Exception {
IgniteEx grid = startGrid(0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest to write a full test with server nodes of 2 appropriate versions: 2.17 and RU-supporting 2.18.

throw new EOFException();

detectSslAlert(hdr);
detectJavaObjectStreamHeader(hdr);
Copy link
Contributor

Choose a reason for hiding this comment

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

How many messages does it affect? TcpDiscoveryHandshakeRequest and TcpDiscoveryPingRequest ? Do we need to check every message? If the additional bytes follow IGNITE_HEADER, we might validate it there. WDYT?

}

try {
if (MESSAGE_SERIALIZATION != serMode) {
Copy link
Contributor Author

@chesnokoff chesnokoff Jan 27, 2026

Choose a reason for hiding this comment

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

Initially, detectJavaObjectStreamHeader was placed after detectSslAlert. The suggestion was to avoid checking serMode after the connection is established.

To achieve this, we need a way to notify session that these checks are no longer required. The current approach is that higher-level code calls switchToFastReader and it swaps the reader implementation. As a result, we eliminate a single if check.

However, to me this looks like a very minor optimization, because I/O dominates the cost compared to a simple conditional. Moreover, it seems to break the DIP, since higher-level code now has to be aware of implementation details of TcpDiscoveryIoSession

Copy link
Contributor

Choose a reason for hiding this comment

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

If we want not to know about the session implementation, we might create another implementation of TcpDiscoveryIoSession which can check the protocol. Not sure worth it. Or we might bring some flag checkCompatibility to the session. At the first connection, we use session with checkCompatibility=true. On next permanent connection, we might recreate session with checkCompatibility=false. This flag is used in the message serialization.


throw new IgniteCheckedException(e);
/** Reads 4-byte header for diagnostics. */
protected byte[] readHeader(byte serMode) throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is colled only from a derived class.

if (MESSAGE_SERIALIZATION != serMode) {
detectSslAlert(serMode, in);
/** Base discovery message reader. */
private abstract class DiscoveryMessageReader {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this abstract class? I would use smth. like DefaultReader (not abstract) and CheckedReader.

}

try {
if (MESSAGE_SERIALIZATION != serMode) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we want not to know about the session implementation, we might create another implementation of TcpDiscoveryIoSession which can check the protocol. Not sure worth it. Or we might bring some flag checkCompatibility to the session. At the first connection, we use session with checkCompatibility=true. On next permanent connection, we might recreate session with checkCompatibility=false. This flag is used in the message serialization.


try {
TcpDiscoveryIoSession ses = createSession(sock);
ses.switchToFastReader();
Copy link
Contributor

Choose a reason for hiding this comment

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

My overal idea is to use different or flagged createSession() so that it would choose which session to create checked or fast. Same in other places of switchToFastReader()

if (MESSAGE_SERIALIZATION != serMode) {
detectSslAlert(serMode, in);
/** Base discovery message reader. */
private abstract class DiscoveryMessageReader {
Copy link
Contributor

Choose a reason for hiding this comment

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

To me, looks as overhead. Too much new code, more complication. We alread have many ifs, switches in the message parsing. I belive, one more wouldn't change the roitine. Instead new subclasses, we might bring to the session some flag like checkProtocol. And just recreate session with/without it.

/** */
public class TcpDiscoveryDifferentClusterVersionsTest extends IgniteCompatibilityAbstractTest {
/** */
private static final String SER_MODE_MSG = "serMode byte is expected";
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 not sure this message is clear to a user. We might say something of an unexpected bytes/reading, old protocol version.

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.

2 participants