produce_request.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package sarama
  2. // RequiredAcks is used in Produce Requests to tell the broker how many replica acknowledgements
  3. // it must see before responding. Any of the constants defined here are valid. On broker versions
  4. // prior to 0.8.2.0 any other positive int16 is also valid (the broker will wait for that many
  5. // acknowledgements) but in 0.8.2.0 and later this will raise an exception (it has been replaced
  6. // by setting the `min.isr` value in the brokers configuration).
  7. type RequiredAcks int16
  8. const (
  9. // NoResponse doesn't send any response, the TCP ACK is all you get.
  10. NoResponse RequiredAcks = 0
  11. // WaitForLocal waits for only the local commit to succeed before responding.
  12. WaitForLocal RequiredAcks = 1
  13. // WaitForAll waits for all replicas to commit before responding.
  14. WaitForAll RequiredAcks = -1
  15. )
  16. type ProduceRequest struct {
  17. RequiredAcks RequiredAcks
  18. Timeout int32
  19. msgSets map[string]map[int32]*MessageSet
  20. }
  21. func (p *ProduceRequest) encode(pe packetEncoder) error {
  22. pe.putInt16(int16(p.RequiredAcks))
  23. pe.putInt32(p.Timeout)
  24. err := pe.putArrayLength(len(p.msgSets))
  25. if err != nil {
  26. return err
  27. }
  28. for topic, partitions := range p.msgSets {
  29. err = pe.putString(topic)
  30. if err != nil {
  31. return err
  32. }
  33. err = pe.putArrayLength(len(partitions))
  34. if err != nil {
  35. return err
  36. }
  37. for id, msgSet := range partitions {
  38. pe.putInt32(id)
  39. pe.push(&lengthField{})
  40. err = msgSet.encode(pe)
  41. if err != nil {
  42. return err
  43. }
  44. err = pe.pop()
  45. if err != nil {
  46. return err
  47. }
  48. }
  49. }
  50. return nil
  51. }
  52. func (p *ProduceRequest) decode(pd packetDecoder) error {
  53. requiredAcks, err := pd.getInt16()
  54. if err != nil {
  55. return err
  56. }
  57. p.RequiredAcks = RequiredAcks(requiredAcks)
  58. if p.Timeout, err = pd.getInt32(); err != nil {
  59. return err
  60. }
  61. topicCount, err := pd.getArrayLength()
  62. if err != nil {
  63. return err
  64. }
  65. if topicCount == 0 {
  66. return nil
  67. }
  68. p.msgSets = make(map[string]map[int32]*MessageSet)
  69. for i := 0; i < topicCount; i++ {
  70. topic, err := pd.getString()
  71. if err != nil {
  72. return err
  73. }
  74. partitionCount, err := pd.getArrayLength()
  75. if err != nil {
  76. return err
  77. }
  78. p.msgSets[topic] = make(map[int32]*MessageSet)
  79. for j := 0; j < partitionCount; j++ {
  80. partition, err := pd.getInt32()
  81. if err != nil {
  82. return err
  83. }
  84. messageSetSize, err := pd.getInt32()
  85. if err != nil {
  86. return err
  87. }
  88. if messageSetSize == 0 {
  89. continue
  90. }
  91. msgSetDecoder, err := pd.getSubset(int(messageSetSize))
  92. if err != nil {
  93. return err
  94. }
  95. msgSet := &MessageSet{}
  96. err = msgSet.decode(msgSetDecoder)
  97. if err != nil {
  98. return err
  99. }
  100. p.msgSets[topic][partition] = msgSet
  101. }
  102. }
  103. return nil
  104. }
  105. func (p *ProduceRequest) key() int16 {
  106. return 0
  107. }
  108. func (p *ProduceRequest) version() int16 {
  109. return 0
  110. }
  111. func (p *ProduceRequest) AddMessage(topic string, partition int32, msg *Message) {
  112. if p.msgSets == nil {
  113. p.msgSets = make(map[string]map[int32]*MessageSet)
  114. }
  115. if p.msgSets[topic] == nil {
  116. p.msgSets[topic] = make(map[int32]*MessageSet)
  117. }
  118. set := p.msgSets[topic][partition]
  119. if set == nil {
  120. set = new(MessageSet)
  121. p.msgSets[topic][partition] = set
  122. }
  123. set.addMessage(msg)
  124. }
  125. func (p *ProduceRequest) AddSet(topic string, partition int32, set *MessageSet) {
  126. if p.msgSets == nil {
  127. p.msgSets = make(map[string]map[int32]*MessageSet)
  128. }
  129. if p.msgSets[topic] == nil {
  130. p.msgSets[topic] = make(map[int32]*MessageSet)
  131. }
  132. p.msgSets[topic][partition] = set
  133. }