8 // MaximumCommandBatchSize bounds the ordered commands in one publication.
9 const MaximumCommandBatchSize = 256
11 // BatchPayload holds 2 through 256 commands for one device. IDs and targets are
12 // distinct. Array order is operation order. Each member keeps its own expiry,
13 // correlation, and causation. There is no combined result.
14 type BatchPayload struct {
15 Commands []BatchCommand
18 // MarshalJSON inserts each command's schema without caller-built envelopes.
19 func (b BatchPayload) MarshalJSON() ([]byte, error) {
20 commands := make([]batchWireCommand, 0, len(b.Commands))
22 for _, command := range b.Commands {
23 commands = append(commands, batchWireCommand{
26 Metadata: command.Metadata,
28 Capability: command.Capability,
30 Payload: command.Payload,
34 data, err := json.Marshal(batchWirePayload{Commands: commands})
36 return nil, fmt.Errorf("encode batch members: %w", err)
42 // UnmarshalJSON rejects unknown fields and unsupported member schemas.
43 func (b *BatchPayload) UnmarshalJSON(data []byte) error {
44 var wire batchWirePayload
46 err := decodeObject(data, &wire)
48 return fmt.Errorf("decode batch members: %w", err)
51 commands := make([]BatchCommand, 0, len(wire.Commands))
53 for _, command := range wire.Commands {
54 if command.Schema != Schema {
55 return fmt.Errorf("unsupported batch member schema %d", command.Schema)
58 commands = append(commands, BatchCommand{
59 Metadata: command.Metadata,
61 Capability: command.Capability,
63 Payload: command.Payload,
72 // BatchCommand holds one complete request without a topic or schema field. The
73 // outer batch message ID equals the first member's message ID.
74 type BatchCommand struct {
80 type batchWirePayload struct {
81 Commands []batchWireCommand `json:"commands"`
84 type batchWireCommand struct {
85 Schema int `json:"schema"`
87 Capability string `json:"capability"`
88 Payload ValuePayload `json:"payload"`