@@ -134,8 +134,9 @@ func (s *sink) createReq(id int64, epoch int16) (*produceRequest, *kmsg.AddParti
134134 recBuf .inflight ++
135135
136136 recBuf .batchDrainIdx ++
137+ recBuf .lockedStopLinger ()
137138 recBuf .seq = incrementSequence (recBuf .seq , int32 (len (batch .records )))
138- moreToDrain = recBuf .tryStopLingerForDraining () || moreToDrain
139+ moreToDrain = recBuf .checkIfShouldDrainOrStartLinger () || moreToDrain
139140 recBuf .mu .Unlock ()
140141
141142 txnBuilder .add (recBuf )
@@ -1384,18 +1385,17 @@ func (recBuf *recBuf) bufferRecord(pr promisedRec, abortOnNewBatch bool) bool {
13841385 }
13851386
13861387 var (
1387- newBatch = true
1388- onDrainBatch = recBuf .batchDrainIdx == len (recBuf .batches )
1388+ mkNewBatch = true
13891389 produceVersion = recBuf .sink .produceVersion .Load ()
13901390 )
13911391
1392- if ! onDrainBatch {
1392+ if recBuf . batchDrainIdx != len ( recBuf . batches ) {
13931393 batch := recBuf .batches [len (recBuf .batches )- 1 ]
13941394 appended , _ := batch .tryBuffer (pr , produceVersion , recBuf .maxRecordBatchBytes , false )
1395- newBatch = ! appended
1395+ mkNewBatch = ! appended
13961396 }
13971397
1398- if newBatch {
1398+ if mkNewBatch {
13991399 newBatch := recBuf .newRecordBatch ()
14001400 appended , aborted := newBatch .tryBuffer (pr , produceVersion , recBuf .maxRecordBatchBytes , abortOnNewBatch )
14011401
@@ -1413,22 +1413,7 @@ func (recBuf *recBuf) bufferRecord(pr promisedRec, abortOnNewBatch bool) bool {
14131413 recBuf .batches = append (recBuf .batches , newBatch )
14141414 }
14151415
1416- if recBuf .cl .cfg .linger == 0 {
1417- if onDrainBatch {
1418- recBuf .sink .maybeDrain ()
1419- }
1420- } else {
1421- // With linger, if this is a new batch but not the first, we
1422- // stop lingering and begin draining. The drain loop will
1423- // restart our linger once this buffer has one batch left.
1424- if newBatch && ! onDrainBatch ||
1425- // If this is the first batch, try lingering; if
1426- // we cannot, we are being flushed and must drain.
1427- onDrainBatch && ! recBuf .lockedMaybeLinger () {
1428- recBuf .lockedStopLinger ()
1429- recBuf .sink .maybeDrain ()
1430- }
1431- }
1416+ recBuf .maybeTriggerDrain ()
14321417
14331418 recBuf .buffered .Add (1 )
14341419 if recBuf .cl .producer .hooks != nil && len (recBuf .cl .producer .hooks .partitioned ) > 0 {
@@ -1440,19 +1425,22 @@ func (recBuf *recBuf) bufferRecord(pr promisedRec, abortOnNewBatch bool) bool {
14401425 return true
14411426}
14421427
1443- // Stops lingering, potentially restarting it, and returns whether there is
1444- // more to drain.
1445- //
1446- // If lingering, if there are more than one batches ready, there is definitely
1447- // more to drain and we should not linger. Otherwise, if we cannot restart
1448- // lingering, then we are flushing and also indicate there is more to drain.
1449- func (recBuf * recBuf ) tryStopLingerForDraining () bool {
1450- recBuf .lockedStopLinger ()
1451- canLinger := recBuf .cl .cfg .linger != 0
1452- moreToDrain := ! canLinger && len (recBuf .batches ) > recBuf .batchDrainIdx ||
1453- canLinger && (len (recBuf .batches ) > recBuf .batchDrainIdx + 1 ||
1454- len (recBuf .batches ) == recBuf .batchDrainIdx + 1 && ! recBuf .lockedMaybeLinger ())
1455- return moreToDrain
1428+ // Maybe drains, maybe starts a linger.
1429+ // Must be called while locked.
1430+ func (recBuf * recBuf ) maybeTriggerDrain () {
1431+ if recBuf .checkIfShouldDrainOrStartLinger () {
1432+ recBuf .lockedStopLinger ()
1433+ recBuf .sink .maybeDrain ()
1434+ }
1435+ }
1436+
1437+ // Checks and returns if we should drain; if not, this potentially starts a
1438+ // linger timer.
1439+ func (recBuf * recBuf ) checkIfShouldDrainOrStartLinger () bool {
1440+ nbufBatches := len (recBuf .batches ) - recBuf .batchDrainIdx
1441+ return recBuf .cl .cfg .linger == 0 && nbufBatches > 0 || // no lingering, and any batch exists? drain
1442+ nbufBatches > 1 || // lingering, and more than one batch exists? drain -- one is full
1443+ nbufBatches == 1 && ! recBuf .lockedMaybeLinger () // only one batch; if we cannot start lingering, we are being flushed or have too much buffered and have to drain
14561444}
14571445
14581446// Begins a linger timer unless the producer is being flushed.
@@ -1584,9 +1572,7 @@ func (recBuf *recBuf) clearFailing() {
15841572 defer recBuf .mu .Unlock ()
15851573
15861574 recBuf .failing = false
1587- if len (recBuf .batches ) != recBuf .batchDrainIdx {
1588- recBuf .sink .maybeDrain ()
1589- }
1575+ recBuf .maybeTriggerDrain ()
15901576}
15911577
15921578func (recBuf * recBuf ) resetBatchDrainIdx () {
@@ -1763,14 +1749,7 @@ func (b *recBatch) decInflight() {
17631749 return
17641750 }
17651751 recBuf .inflightOnSink = nil
1766-
1767- nbufBatches := len (recBuf .batches ) - recBuf .batchDrainIdx
1768- if recBuf .cl .cfg .linger == 0 && nbufBatches > 0 ||
1769- nbufBatches > 1 ||
1770- nbufBatches == 1 && ! recBuf .lockedMaybeLinger () {
1771- recBuf .lockedStopLinger ()
1772- recBuf .sink .maybeDrain ()
1773- }
1752+ recBuf .maybeTriggerDrain ()
17741753}
17751754
17761755////////////////////
0 commit comments