Repository: valkey-io/valkey
File: src/cluster_legacy.h (C/C++)

Code before:
static_assert(offsetof(clusterMsg, notused1) == 2216, "unexpected field offset");
static_assert(offsetof(clusterMsg, pport) == 2246, "unexpected field offset");
static_assert(offsetof(clusterMsg, cport) == 2248, "unexpected field offset");
static_assert(offsetof(clusterMsg, flags) == 2250, "unexpected field offset");
static_assert(offsetof(clusterMsg, state) == 2252, "unexpected field offset");
static_assert(offsetof(clusterMsg, mflags) == 2253, "unexpected field offset");
static_assert(offsetof(clusterMsg, data) == 2256, "unexpected field offset");

#define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg) - sizeof(union clusterMsgData))

/* Message flags better specify the packet content or are used to
 * provide some information about the node state. */
#define CLUSTERMSG_FLAG0_PAUSED (1 << 0) /* Primary paused for manual failover. */
#define CLUSTERMSG_FLAG0_FORCEACK                                                                                      \
    (1 << 1)                               /* Give ACK to AUTH_REQUEST even if                                         \
                                              primary is up. */
#define CLUSTERMSG_FLAG0_EXT_DATA (1 << 2) /* Message contains extension data */

typedef struct {
    char sig[4];                  /* Signature "RCmb" (Cluster message bus). */
    uint32_t totlen;              /* Total length of this message */
    uint16_t ver;                 /* Protocol version, currently set to CLUSTER_PROTO_VER. */
    uint16_t port;                /* Primary port number (TCP or TLS). */
    uint16_t type;                /* Message type */
    union clusterMsgData data;
} clusterMsgPubsub;


static_assert(offsetof(clusterMsgPubsub, sig) == 0, "unexpected field offset");
static_assert(offsetof(clusterMsgPubsub, totlen) == 4, "unexpected field offset");
static_assert(offsetof(clusterMsgPubsub, ver) == 8, "unexpected field offset");
static_assert(offsetof(clusterMsgPubsub, port) == 10, "unexpected field offset");
static_assert(offsetof(clusterMsgPubsub, type) == 12, "unexpected field offset");
static_assert(offsetof(clusterMsgPubsub, data) == 16, "unexpected field offset");

#define CLUSTERMSGPUBSUB_MIN_LEN (sizeof(clusterMsgPubsub) - sizeof(union clusterMsgData))

struct _clusterNode {
    mstime_t ctime;                         /* Node object creation time. */
    char name[CLUSTER_NAMELEN];             /* Node name, hex string, sha1-size */
    char shard_id[CLUSTER_NAMELEN];         /* shard id, hex string, sha1-size */
    int flags;                              /* CLUSTER_NODE_... */
    uint64_t configEpoch;                   /* Last configEpoch observed for this node */
    unsigned char slots[CLUSTER_SLOTS / 8]; /* slots handled by this node */
    uint16_t *slot_info_pairs;              /* Slots info represented as (start/end) pair (consecutive index). */
    int slot_info_pairs_count;              /* Used number of slots in slot_info_pairs */
    int numslots;                           /* Number of slots handled by this node */
    int num_replicas;                       /* Number of replica nodes, if this is a primar */
    clusterNode **replicas;                 /* pointers to replica nodes */
    clusterNode *replicaof;                 /* pointer to the primary node. Note that it
                                             may be NULL even if the node is a replica

Review comment (suggestion):
* This struct doesn't contain anything pubsub specific, so we can just call it clusterMsgLight and later we can allow other light messages in the union.

* We don't need the port, but we need `type` to be at the correct offset. Let's rename port to `notused` or `notused1` like in some other structs. (Or we can use it for something else, such as how many data messages are included?)

* The `union clusterMsgData` allows MEET, PONG and other messages that we don't want to allow in the light message, so I think we can use a new union type for this, where the only possible member right now is the pubsub message.

* We can consider defining a new clusterMsgPubsubMulti (or better name?) which can contain many messages for the same channel?

```C
typedef struct {
    uint32_t message_len;
    unsigned char data[];
} clusterMsgDataPublishMessage;

typedef struct {
    uint16_t channel_len;
    uint16_t message_count;
    clusterMsgDataPublishMessage messages[];
} clusterMsgDataPublishMulti;
```

16 bits for channel name is enough I hope. I don't want this to be larger than an old clusterMsgDataPublish. :)

Code after:
 * Therefore, fields in this struct should remain at the same offset from
 * release to release. The static asserts below ensures that incompatible
 * changes in clusterMsg be caught at compile time.
 */

static_assert(offsetof(clusterMsg, sig) == 0, "unexpected field offset");
static_assert(offsetof(clusterMsg, totlen) == 4, "unexpected field offset");
static_assert(offsetof(clusterMsg, ver) == 8, "unexpected field offset");
static_assert(offsetof(clusterMsg, port) == 10, "unexpected field offset");
static_assert(offsetof(clusterMsg, type) == 12, "unexpected field offset");
static_assert(offsetof(clusterMsg, count) == 14, "unexpected field offset");
static_assert(offsetof(clusterMsg, currentEpoch) == 16, "unexpected field offset");
static_assert(offsetof(clusterMsg, configEpoch) == 24, "unexpected field offset");
static_assert(offsetof(clusterMsg, offset) == 32, "unexpected field offset");
static_assert(offsetof(clusterMsg, sender) == 40, "unexpected field offset");
static_assert(offsetof(clusterMsg, myslots) == 80, "unexpected field offset");
static_assert(offsetof(clusterMsg, replicaof) == 2128, "unexpected field offset");
static_assert(offsetof(clusterMsg, myip) == 2168, "unexpected field offset");
static_assert(offsetof(clusterMsg, extensions) == 2214, "unexpected field offset");
static_assert(offsetof(clusterMsg, notused1) == 2216, "unexpected field offset");
static_assert(offsetof(clusterMsg, pport) == 2246, "unexpected field offset");
static_assert(offsetof(clusterMsg, cport) == 2248, "unexpected field offset");
static_assert(offsetof(clusterMsg, flags) == 2250, "unexpected field offset");
static_assert(offsetof(clusterMsg, state) == 2252, "unexpected field offset");
static_assert(offsetof(clusterMsg, mflags) == 2253, "unexpected field offset");
static_assert(offsetof(clusterMsg, data) == 2256, "unexpected field offset");

#define CLUSTERMSG_MIN_LEN (sizeof(clusterMsg) - sizeof(union clusterMsgData))

/* Message flags better specify the packet content or are used to
 * provide some information about the node state. */
#define CLUSTERMSG_FLAG0_PAUSED (1 << 0) /* Primary paused for manual failover. */
#define CLUSTERMSG_FLAG0_FORCEACK                                                                                      \
    (1 << 1)                               /* Give ACK to AUTH_REQUEST even if                                         \
                                              primary is up. */
#define CLUSTERMSG_FLAG0_EXT_DATA (1 << 2) /* Message contains extension data */

typedef struct {
    char sig[4];     /* Signature "RCmb" (Cluster message bus). */
    uint32_t totlen; /* Total length of this message */
    uint16_t ver;    /* Protocol version, currently set to CLUSTER_PROTO_VER. */
    uint16_t notused1;
    uint16_t type; /* Message type */
    uint16_t notused2;
    union clusterMsgData data;
} clusterMsgLight;

static_assert(offsetof(clusterMsgLight, sig) == offsetof(clusterMsg, sig), "unexpected field offset");
static_assert(offsetof(clusterMsgLight, totlen) == offsetof(clusterMsg, totlen), "unexpected field offset");
static_assert(offsetof(clusterMsgLight, ver) == offsetof(clusterMsg, ver), "unexpected field offset");
static_assert(offsetof(clusterMsgLight, notused1) == offsetof(clusterMsg, port), "unexpected field offset");