Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#550 fix race condition when resend pendingItems #551

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 33 additions & 9 deletions pulsar/producer_partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,29 @@ func (p *partitionProducer) grabCnx() error {
p.log.WithField("cnx", res.Cnx.ID()).Debug("Connected producer")

pendingItems := p.pendingQueue.ReadableSlice()
if len(pendingItems) > 0 {
p.log.Infof("Resending %d pending batches", len(pendingItems))
for _, pi := range pendingItems {
p.cnx.WriteData(pi.(*pendingItem).batchData)
viewSize := len(pendingItems)
if viewSize > 0 {
p.log.Infof("Resending %d pending batches", viewSize)
lastViewItem := pendingItems[viewSize-1].(*pendingItem)

// iterate at most pending items
for i := 0; i < viewSize; i++ {
item := p.pendingQueue.Poll()
if item == nil {
continue
}
pi := item.(*pendingItem)
// when resending pending batches, we update the sendAt timestamp and put to the back of queue
// to avoid pending item been removed by failTimeoutMessages and cause race condition
pi.Lock()
pi.sentAt = time.Now()
pi.Unlock()
p.pendingQueue.Put(pi)
p.cnx.WriteData(pi.batchData)

if pi == lastViewItem {
break
}
}
}
return nil
Expand Down Expand Up @@ -523,8 +542,7 @@ func (p *partitionProducer) failTimeoutMessages() {
}

// flag the send has completed with error, flush make no effect
pi.completed = true
buffersPool.Put(pi.batchData)
pi.Complete()
pi.Unlock()

// finally reached the last view item, current iteration ends
Expand Down Expand Up @@ -706,9 +724,7 @@ func (p *partitionProducer) ReceivedSendReceipt(response *pb.CommandSendReceipt)
}

// Mark this pending item as done
pi.completed = true
// Return buffer to the pool since we're now done using it
buffersPool.Put(pi.batchData)
pi.Complete()
}

func (p *partitionProducer) internalClose(req *closeProducer) {
Expand Down Expand Up @@ -800,3 +816,11 @@ type flushRequest struct {
waitGroup *sync.WaitGroup
err error
}

func (i *pendingItem) Complete() {
if i.completed {
return
}
i.completed = true
buffersPool.Put(i.batchData)
}