|
@@ -777,163 +777,6 @@ func (p *asyncProducer) retryHandler() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-type partitionSet struct {
|
|
|
- msgs []*ProducerMessage
|
|
|
- setToSend *MessageSet
|
|
|
- bufferBytes int
|
|
|
-}
|
|
|
-
|
|
|
-type produceSet struct {
|
|
|
- parent *asyncProducer
|
|
|
- msgs map[string]map[int32]*partitionSet
|
|
|
-
|
|
|
- bufferBytes int
|
|
|
- bufferCount int
|
|
|
-}
|
|
|
-
|
|
|
-func newProduceSet(parent *asyncProducer) *produceSet {
|
|
|
- return &produceSet{
|
|
|
- msgs: make(map[string]map[int32]*partitionSet),
|
|
|
- parent: parent,
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) add(msg *ProducerMessage) error {
|
|
|
- var err error
|
|
|
- var key, val []byte
|
|
|
-
|
|
|
- if msg.Key != nil {
|
|
|
- if key, err = msg.Key.Encode(); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if msg.Value != nil {
|
|
|
- if val, err = msg.Value.Encode(); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- partitions := ps.msgs[msg.Topic]
|
|
|
- if partitions == nil {
|
|
|
- partitions = make(map[int32]*partitionSet)
|
|
|
- ps.msgs[msg.Topic] = partitions
|
|
|
- }
|
|
|
-
|
|
|
- set := partitions[msg.Partition]
|
|
|
- if set == nil {
|
|
|
- set = &partitionSet{setToSend: new(MessageSet)}
|
|
|
- partitions[msg.Partition] = set
|
|
|
- }
|
|
|
-
|
|
|
- set.msgs = append(set.msgs, msg)
|
|
|
- set.setToSend.addMessage(&Message{Codec: CompressionNone, Key: key, Value: val})
|
|
|
-
|
|
|
- size := producerMessageOverhead + len(key) + len(val)
|
|
|
- set.bufferBytes += size
|
|
|
- ps.bufferBytes += size
|
|
|
- ps.bufferCount++
|
|
|
-
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) buildRequest() *ProduceRequest {
|
|
|
- req := &ProduceRequest{
|
|
|
- RequiredAcks: ps.parent.conf.Producer.RequiredAcks,
|
|
|
- Timeout: int32(ps.parent.conf.Producer.Timeout / time.Millisecond),
|
|
|
- }
|
|
|
-
|
|
|
- for topic, partitionSet := range ps.msgs {
|
|
|
- for partition, set := range partitionSet {
|
|
|
- if ps.parent.conf.Producer.Compression == CompressionNone {
|
|
|
- req.AddSet(topic, partition, set.setToSend)
|
|
|
- } else {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- payload, err := encode(set.setToSend)
|
|
|
- if err != nil {
|
|
|
- Logger.Println(err)
|
|
|
- panic(err)
|
|
|
- }
|
|
|
- req.AddMessage(topic, partition, &Message{
|
|
|
- Codec: ps.parent.conf.Producer.Compression,
|
|
|
- Key: nil,
|
|
|
- Value: payload,
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return req
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) eachPartition(cb func(topic string, partition int32, msgs []*ProducerMessage)) {
|
|
|
- for topic, partitionSet := range ps.msgs {
|
|
|
- for partition, set := range partitionSet {
|
|
|
- cb(topic, partition, set.msgs)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) dropPartition(topic string, partition int32) []*ProducerMessage {
|
|
|
- if ps.msgs[topic] == nil {
|
|
|
- return nil
|
|
|
- }
|
|
|
- set := ps.msgs[topic][partition]
|
|
|
- if set == nil {
|
|
|
- return nil
|
|
|
- }
|
|
|
- ps.bufferBytes -= set.bufferBytes
|
|
|
- ps.bufferCount -= len(set.msgs)
|
|
|
- delete(ps.msgs[topic], partition)
|
|
|
- return set.msgs
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) wouldOverflow(msg *ProducerMessage) bool {
|
|
|
- switch {
|
|
|
-
|
|
|
- case ps.bufferBytes+msg.byteSize() >= int(MaxRequestSize-(10*1024)):
|
|
|
- return true
|
|
|
-
|
|
|
- case ps.parent.conf.Producer.Compression != CompressionNone &&
|
|
|
- ps.msgs[msg.Topic] != nil && ps.msgs[msg.Topic][msg.Partition] != nil &&
|
|
|
- ps.msgs[msg.Topic][msg.Partition].bufferBytes+msg.byteSize() >= ps.parent.conf.Producer.MaxMessageBytes:
|
|
|
- return true
|
|
|
-
|
|
|
- case ps.parent.conf.Producer.Flush.MaxMessages > 0 && ps.bufferCount >= ps.parent.conf.Producer.Flush.MaxMessages:
|
|
|
- return true
|
|
|
- default:
|
|
|
- return false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) readyToFlush() bool {
|
|
|
- switch {
|
|
|
-
|
|
|
- case ps.empty():
|
|
|
- return false
|
|
|
-
|
|
|
- case ps.parent.conf.Producer.Flush.Frequency == 0 && ps.parent.conf.Producer.Flush.Bytes == 0 && ps.parent.conf.Producer.Flush.Messages == 0:
|
|
|
- return true
|
|
|
-
|
|
|
- case ps.parent.conf.Producer.Flush.Messages > 0 && ps.bufferCount >= ps.parent.conf.Producer.Flush.Messages:
|
|
|
- return true
|
|
|
-
|
|
|
- case ps.parent.conf.Producer.Flush.Bytes > 0 && ps.bufferBytes >= ps.parent.conf.Producer.Flush.Bytes:
|
|
|
- return true
|
|
|
- default:
|
|
|
- return false
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (ps *produceSet) empty() bool {
|
|
|
- return ps.bufferCount == 0
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
|
|
|
func (p *asyncProducer) shutdown() {
|