diff --git a/docs/manual/config/config_file_reference.rst b/docs/manual/config/config_file_reference.rst index 8e68a65772..567c33032f 100644 --- a/docs/manual/config/config_file_reference.rst +++ b/docs/manual/config/config_file_reference.rst @@ -843,11 +843,23 @@ The default value is: ``writers`` //CycloneDDS/Domain/Internal/BurstSize -------------------------------------- -Children: `//CycloneDDS/Domain/Internal/BurstSize/MaxInitTransmit`_, `//CycloneDDS/Domain/Internal/BurstSize/MaxRexmit`_ +Children: `//CycloneDDS/Domain/Internal/BurstSize/MaxFragsRexmitSample`_, `//CycloneDDS/Domain/Internal/BurstSize/MaxInitTransmit`_, `//CycloneDDS/Domain/Internal/BurstSize/MaxRexmit`_ Setting for controlling the size of transmitting bursts. +.. _`//CycloneDDS/Domain/Internal/BurstSize/MaxFragsRexmitSample`: + +//CycloneDDS/Domain/Internal/BurstSize/MaxFragsRexmitSample +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Text + +This element controls the maximum number of fragments of a sample that are retransmit in response to a NACK of the entire sample (as opposed to what is sent in response to a NACKFRAG requesting specific fragments). + +The default value is: ``1`` + + .. _`//CycloneDDS/Domain/Internal/BurstSize/MaxInitTransmit`: //CycloneDDS/Domain/Internal/BurstSize/MaxInitTransmit @@ -2628,10 +2640,10 @@ The categorisation of tracing output is incomplete and hence most of the verbosi The default value is: ``none`` .. - generated from ddsi_config.h[eae21b4181f3fdd23b2514a089c43b0e36357066] + generated from ddsi_config.h[570f67bd3080674a4bad53d9580a8bb7ad1e6e4d] generated from ddsi__cfgunits.h[bd22f0c0ed210501d0ecd3b07c992eca549ef5aa] - generated from ddsi__cfgelems.h[0d5a3d2063031f4b47f53cc007d2703bcdefdfa1] - generated from ddsi_config.c[7b5f868237256aa44f09a4ef5b411a21a5ca8024] + generated from ddsi__cfgelems.h[13337a006d5313519c88c3f3643f27992840cfd3] + generated from ddsi_config.c[efeae198a5e12ca8977a655216470564b5c44b64] generated from _confgen.h[e32eabfc35e9f3a7dcb63b19ed148c0d17c6e5fc] generated from _confgen.c[237308acd53897a34e8c643e16e05a61d73ffd65] generated from generate_rnc.c[b50e4b7ab1d04b2bc1d361a0811247c337b74934] diff --git a/docs/manual/options.md b/docs/manual/options.md index 141b020a84..1071cd05f1 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -566,11 +566,19 @@ The default value is: `writers` #### //CycloneDDS/Domain/Internal/BurstSize -Children: [MaxInitTransmit](#cycloneddsdomaininternalburstsizemaxinittransmit), [MaxRexmit](#cycloneddsdomaininternalburstsizemaxrexmit) +Children: [MaxFragsRexmitSample](#cycloneddsdomaininternalburstsizemaxfragsrexmitsample), [MaxInitTransmit](#cycloneddsdomaininternalburstsizemaxinittransmit), [MaxRexmit](#cycloneddsdomaininternalburstsizemaxrexmit) Setting for controlling the size of transmitting bursts. +##### //CycloneDDS/Domain/Internal/BurstSize/MaxFragsRexmitSample +Text + +This element controls the maximum number of fragments of a sample that are retransmit in response to a NACK of the entire sample (as opposed to what is sent in response to a NACKFRAG requesting specific fragments). + +The default value is: `1` + + ##### //CycloneDDS/Domain/Internal/BurstSize/MaxInitTransmit Number-with-unit @@ -1836,10 +1844,10 @@ While none prevents any message from being written to a DDSI2 log file. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest. The default value is: `none` - + - - + + diff --git a/etc/cyclonedds.rnc b/etc/cyclonedds.rnc index 6670c0fd6a..b1e1438071 100644 --- a/etc/cyclonedds.rnc +++ b/etc/cyclonedds.rnc @@ -407,6 +407,12 @@ CycloneDDS configuration""" ] ]
Setting for controlling the size of transmitting bursts.
""" ] ] element BurstSize { [ a:documentation [ xml:lang="en" """ +This element controls the maximum number of fragments of a sample that are retransmit in response to a NACK of the entire sample (as opposed to what is sent in response to a NACKFRAG requesting specific fragments).
+The default value is: 1
This element specifies how much more than the (presumed or discovered) receive buffer size may be sent when transmitting a sample for the first time, expressed as a percentage; the remainder will then be handled via retransmits. Usually, the receivers can keep up with the transmitter, at least on average, so generally it is better to hope for the best and recover. Besides, the retransmits will be unicast, and so any multicast advantage will be lost as well.
The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).
The default value is: 4294967295
This element controls the maximum number of fragments of a sample that " + "are retransmit in response to a NACK of the entire sample (as opposed to " + "what is sent in response to a NACKFRAG requesting specific fragments).
")), END_MARKER }; diff --git a/src/core/ddsi/src/ddsi_config.c b/src/core/ddsi/src/ddsi_config.c index 7910b67eae..52c9d624b9 100644 --- a/src/core/ddsi/src/ddsi_config.c +++ b/src/core/ddsi/src/ddsi_config.c @@ -162,6 +162,7 @@ DUPF(uint32); #endif DU(natint); DU(natint_255); +DU(pos_uint); DUPF(participantIndex); DU(dyn_port); DUPF(memsize); @@ -1418,6 +1419,16 @@ static enum update_result uf_uint (struct ddsi_cfgst *cfgst, void *parent, struc return URES_SUCCESS; } +static enum update_result uf_pos_uint (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + uint32_t * const elem = cfg_address (cfgst, parent, cfgelem); + int64_t x; + if (uf_int64_unit (cfgst, &x, value, NULL, 1, 1, UINT32_MAX) != URES_SUCCESS) + return URES_ERROR; + *elem = (uint32_t) x; + return URES_SUCCESS; +} + static void pf_uint (struct ddsi_cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, uint32_t sources) { uint32_t const * const p = cfg_address (cfgst, parent, cfgelem); diff --git a/src/core/ddsi/src/ddsi_transmit.c b/src/core/ddsi/src/ddsi_transmit.c index c6d65dd187..4312702faf 100644 --- a/src/core/ddsi/src/ddsi_transmit.c +++ b/src/core/ddsi/src/ddsi_transmit.c @@ -486,8 +486,15 @@ int ddsi_enqueue_sample_wrlock_held (struct ddsi_writer *wr, ddsi_seqno_t seq, s /* end-of-transaction messages are empty, but still need to be sent */ nfrags = 1; } - if (!isnew && nfrags > 1) - nfrags = 1; + if (!isnew && nfrags > gv->config.max_frags_in_rexmit_of_sample) + { + /* Implementations that never use NACKFRAG are allowed by the specification and for such a peer, + we must always respond with the full sample on a NACK. For all other implementations (and + certainly for Cyclone) it makes much more sense to do a small initial retransmit. + + (I am not aware of any implementations that never use NACKFRAG.) */ + nfrags = gv->config.max_frags_in_rexmit_of_sample; + } for (i = 0; i < nfrags && enqueued != DDSI_QXEV_MSG_REXMIT_DROPPED; i++) { struct ddsi_xmsg *fmsg = NULL; @@ -508,7 +515,11 @@ int ddsi_enqueue_sample_wrlock_held (struct ddsi_writer *wr, ddsi_seqno_t seq, s } else { - /* Implementations that never use NACKFRAG are allowed by the specification, and for such a peer, we must always force out the full sample on a retransmit request. I am not aware of any such implementations so leaving the override flag in, but not actually using it at the moment. Should set force = (i != 0) for "known bad" implementations. */ + /* For implementations that never use NACKFRAG if we enqueue the first fragment, we must enqueue + everything, because dropping the tail is guaranteed to result in another full NACK anyway. + + I am not aware of any such implementations so leaving the override flag in, if it turns out they do + exist, set force = (i != 0) for "known bad" implementations. */ const int force = 0; if(fmsg) {