EncodeNodeMetadata encodes node metadata into a compact binary format. The encoding is versioned to allow future extensions while maintaining backward compatibility. We use a custom compact encoding rather than protobuf because memberlist has strict size limits for node metadata (typically 512 byte
(role NodeRole, zone string)
| 28 | // |
| 29 | // The maximum metadata size is 19 bytes (1 + 1 + 1 + 16). |
| 30 | func EncodeNodeMetadata(role NodeRole, zone string) ([]byte, error) { |
| 31 | // Validate zone name length. |
| 32 | zoneLen := len(zone) |
| 33 | if zoneLen > MaxZoneNameLength { |
| 34 | return nil, fmt.Errorf("zone name too long: %d bytes (max %d)", zoneLen, MaxZoneNameLength) |
| 35 | } |
| 36 | |
| 37 | // Allocate buffer: version(1) + role(1) + zone_len(1) + zone(variable). |
| 38 | buf := make([]byte, 3+zoneLen) |
| 39 | |
| 40 | // Encode version. |
| 41 | buf[0] = 1 |
| 42 | |
| 43 | // Encode role. |
| 44 | buf[1] = uint8(role) |
| 45 | |
| 46 | // Encode zone length. |
| 47 | buf[2] = uint8(zoneLen) |
| 48 | |
| 49 | // Encode zone string. |
| 50 | copy(buf[3:], zone) |
| 51 | |
| 52 | return buf, nil |
| 53 | } |
| 54 | |
| 55 | // Role returns the node role with zero allocations. |
| 56 | // Returns NodeRoleMember if the metadata is invalid. |