Background
PR #675 introduces DbBatchSetTable / DbBatchDelTable on MixedDbClient, which collapse multi-key gNMI Set payloads into a single batched ZMQ message via ZmqProducerBatchedSet / ZmqProducerBatchedDel (added in sonic-swss-common#1188).
libswsscommon's ZMQ transport caps a single message at MQ_RESPONSE_MAX_COUNT = 16 MiB (see common/zmqserver.h and the size check in ZmqClient::sendMsg in common/zmqclient.cpp). When the cap is exceeded, the send fails outright.
Per @prabhataravind's review comment:
At 125K+ entries, this single ZMQ message will exceed MQ_RESPONSE_MAX_COUNT (16MB). We will revisit that later based on tests.
A realistic DASH route entry serializes to ~200 B, so a single batched message tops out at roughly 80k entries. Real-world DASH bulk updates can exceed that.
Problem
DbBatchSetTable / DbBatchDelTable currently send the whole batch as one ZMQ message regardless of size. Above the 16 MiB cap the send will fail and the entire gNMI Set is rejected.
Proposed work
- Add size-aware chunking inside
DbBatchSetTable and DbBatchDelTable:
- Estimate per-entry serialized size (key + field/value pairs) as entries are appended to the SWIG vectors.
- When the accumulated size approaches a configurable threshold (suggest 12-14 MiB to leave headroom for ZMQ framing), flush the current chunk via
ZmqProducerBatchedSet/Del and start a new one.
- Preserve ordering across chunks within a single
DbBatchSetTable / DbBatchDelTable call.
- Decide on failure semantics: today the operation is all-or-nothing per ZMQ message. With chunking, a mid-batch failure can leave a partial state. Options:
- Best-effort: continue sending remaining chunks, return the first error.
- Fail-fast: stop on first error.
- Document either way in the helper docstrings.
- Add a regression test exercising a payload that would exceed 16 MiB if sent as a single message.
- (Optional) Make the chunk threshold tunable via env var or config for testbeds with non-default
MQ_RESPONSE_MAX_COUNT.
Alternatives considered
Raising MQ_RESPONSE_MAX_COUNT in sonic-swss-common was discussed in PR #26679 review. It is not free — MQ_RESPONSE_MAX_COUNT drives m_sendbuffer.resize() on every ZMQ client and m_buffer.resize() on every ZMQ server, so every process grows by the new size whether it uses big messages or not. Client-side chunking in sonic-gnmi is the proper fix.
References
Background
PR #675 introduces
DbBatchSetTable/DbBatchDelTableonMixedDbClient, which collapse multi-key gNMI Set payloads into a single batched ZMQ message viaZmqProducerBatchedSet/ZmqProducerBatchedDel(added in sonic-swss-common#1188).libswsscommon's ZMQ transport caps a single message atMQ_RESPONSE_MAX_COUNT = 16 MiB(seecommon/zmqserver.hand the size check inZmqClient::sendMsgincommon/zmqclient.cpp). When the cap is exceeded, the send fails outright.Per @prabhataravind's review comment:
A realistic DASH route entry serializes to ~200 B, so a single batched message tops out at roughly 80k entries. Real-world DASH bulk updates can exceed that.
Problem
DbBatchSetTable/DbBatchDelTablecurrently send the whole batch as one ZMQ message regardless of size. Above the 16 MiB cap the send will fail and the entire gNMI Set is rejected.Proposed work
DbBatchSetTableandDbBatchDelTable:ZmqProducerBatchedSet/Deland start a new one.DbBatchSetTable/DbBatchDelTablecall.MQ_RESPONSE_MAX_COUNT.Alternatives considered
Raising
MQ_RESPONSE_MAX_COUNTinsonic-swss-commonwas discussed in PR #26679 review. It is not free —MQ_RESPONSE_MAX_COUNTdrivesm_sendbuffer.resize()on every ZMQ client andm_buffer.resize()on every ZMQ server, so every process grows by the new size whether it uses big messages or not. Client-side chunking in sonic-gnmi is the proper fix.References