Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Goal is a communication protocol that able to work between nodes with different Ignite versions.

It is proposed to work between versions that differ by 1 minor version, for example 2.20.X between 2.19.X (but not between 2.20.X and 2.18.X).

...

Communication protocol

Communication protocol consist of 2 parts:

  1. Data - set of declared Message classes, including ser/des algorithm.
  2. Transport - algorithm of transport the Messages to remote node.

Data compatibility

Message - is base class for all messages transported between nodes. Proposed changes:

  1. Message#writeTo consumes IgniteProductVersion of destination node and use it for serializing data for this version (mostly, for ignoring some fields).
  2. Message#readFrom consumes IgniteProductVersion of source node and use it for deserializing data (mostly, for setting default values of new fields).

    Code Block
    languagejava
    titleMessage
    public interface Message {    public boolean writeTo(ByteBuffer buf, MessageWriter writer, IgniteProductVersion destVer);
    
        public boolean readFrom(ByteBuffer buf, MessageReader reader, IgniteProductVersion srcVer);
    
        public short directType();}


  3. Introduce annotations @Since and @Until for Message classes and Message fields, to use it for generating code for Message#writeTo and Message#readFrom:

Code Block
languagejava
titleMyMessage
@Since(version = "2.19.0")
public class MyMessage {
    private int id;
    
    @Until(version = "2.20.0")
    private String rmFld;

    @Since(version = "2.20.0")
    private String newFld;

        @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer, IgniteProductVersion destVer) {
        if (destVer.greaterThanEqual(2, 19, 0))
            throw new IgniteException("Must not send the message to destination node");

        if (!writer.writeString(id))
            return false;

        if (destVer.lessThan(2, 20, 0)) {
            if (!writer.writeString(rmFld))
                return false;
        }

        if (destVer.greaterThanEqual(2, 20, 0)) {
            if (!writer.writeString(newFld))
                return false;
        }

        return true;
    }

}




Introduce Communication Protocol Version (ProtoVer) that depends on changes in the parts:

...

  1. It's prohibited to remove fields, change types of fields in Messages. Only adding new fields is allowed.
  2. Breaking changes are introduced as communication features (FeatureMaskFeatureTable).
    1. Every communication feature must be declared with @since Ignite version.
    2. Ignite release must disable a communication feature with Ignite node with (@since - 1) version. 
    3. On release Ignite should check the @since version and notify release manager to drop support of old versions.

...

In Stable mode logic of exchanging messages is not changed. Between nodes open channel, messages are written to the channel one by one as byte stream. There is no delimeters between messages, each message starts with direct type. Reader knows reads full message with Message#readFrom logic.

Message headerMessage

2 bytes: direct type

fields

Rolling upgrade mode 

In Rolling upgrade mode logic is different, because node can't know whether it reads full message - Message#readFrom can't guarantee that.

...