Versions Compared

Key

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

...

  1. MessageWriter, MessageReader logic is depends on a remote IgniteProductVersion.
  2. Message#writeTo, Message#readFrom is auto-generated and stored separately from Message classes.
  3. Add Message#writeObject - for serializing Objects (java functions, and user objects) :
    1. MessageWriter for communication protocol use BinaryMarshaller
    2. MessageWriter for discovery protocol use JdkMarshaller
     with  BinaryMarshaller.
  4. Message fields may containMessage fields contain:
    1. primitive classes.
    2. known collections.
    3. POJO - that are other others Message.
    4. Users classes and java functions (e.g. ComputeJob).
    5. byte[] fields (objects serialized externally) must be avoided as much as possible, because their compatibility can't be guaranteed.
  5. Order of fields in Message is fixed with @Order annotation.
  6. Adding and removing fields must be go along with @Since, @Until annotations for Message classes and fields.

...

  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. Deprecate Message#writeTo and Message#readFrom in favor generated MessageSerializer
  2. MessageSerializer#writeTo Message#writeTo consumes MessageWriter that stores IgniteProductVersion of a receiver node and use it for serializing data for this version (mostly, for ignoring some fields).
  3. Message#readFrom MessageSerializer#readFrom consumes MessageReader that stores IgniteProductVersion of source node and use it for deserializing data (mostly, for setting default values of new fields).

    Code Block
    languagejava
    titleMessage
    public interface MessageSerializer {
        public boolean writeTo(Message msg, ByteBuffer buf, MessageWriter writer);
    
        public boolean readFrom(Message msg, ByteBuffer buf, MessageReader reader);
    }
    
    public interface MessageWriter {
         public IgniteProductVersion receiverVersion();
    }
    
    public interface MessageReader {
         public IgniteProductVersion senderVersion();
    }


  4. 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
// Package where the Message is defined.
package org.apache.ignite.internal.my.message;

@Since(version = "2.19.0")
public class MyMessage implements Message {
    @Order(0)
    private int id;
    
 	/** Remove field. */
    @Until(version = "2.20.0")
    @Order(1)
    private String rmFld;

    /** New field. */
    @Since(version = "2.20.0")
 	@Order(2)
    private String newFld;

	// Message must have setters/getters for all @Ordered fields. Methods names are equal to a corresponding field name. 
	public void id(int id) {
		this.id = id;
	}

  	public int id() {
		return id;
	}

  	public void newFld(String newFld) {
		this.newFld = newFld;
	}
 
 	public String newFld() {
		return newFld;
	}

    // Delegates #writeTo method call to generated serializer.
    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
        return MyMessageSerializer.writeTo(this, buf, writer);
    }

 	// Delegates #readFrom method call to generated serializer.
    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
         return MyMessageSerializer.readFrom(this, buf, reader);
    }
}

// Generated code from the message ^ for Ignite version 2.20.0.
// Use the same package as corresponding message.
package org.apache.ignite.internal.my.message;

class MyMessageSerializer {
    public static boolean writeTo(MyMessageMessage msgm, MByteBufferByteBuffer buf, MessageWriter writer) {
		MyMessage msg       = (MyMessage)m;

		IgniteProductVersion rcvVer = writer.receiverVersion();

        writer.writeString(msg.id());

        if (rcvVer.lessThan(2, 20, 0))
            writer.writeString(msg.rmFld());

        if (rcvVer.greaterThanEqual(2, 20, 0))
            writer.writeString(msg.newFld());
    
        return true;
    }

    public static boolean readFrom(MyMessageMessage msgm, ByteBuffer buf, MessageReader reader) {
 		MyMessage msg = (MyMessage)m;
 
        IgniteProductVersion srcVer = reader.senderVersion();

        msg.id(reader.readString());

		if (srcVer.lessThan(2, 20, 0))
			msg.rmFld(reader.readString());

        if (srcVer.greaterThanEqual(2, 20, 0))
            msg.newFld(reader.readString());

        return true;
    }
}

...