fetch_request.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package sarama
  2. type fetchRequestBlock struct {
  3. Version int16
  4. currentLeaderEpoch int32
  5. fetchOffset int64
  6. logStartOffset int64
  7. maxBytes int32
  8. }
  9. func (b *fetchRequestBlock) encode(pe packetEncoder, version int16) error {
  10. b.Version = version
  11. if b.Version >= 9 {
  12. pe.putInt32(b.currentLeaderEpoch)
  13. }
  14. pe.putInt64(b.fetchOffset)
  15. if b.Version >= 5 {
  16. pe.putInt64(b.logStartOffset)
  17. }
  18. pe.putInt32(b.maxBytes)
  19. return nil
  20. }
  21. func (b *fetchRequestBlock) decode(pd packetDecoder, version int16) (err error) {
  22. b.Version = version
  23. if b.Version >= 9 {
  24. if b.currentLeaderEpoch, err = pd.getInt32(); err != nil {
  25. return err
  26. }
  27. }
  28. if b.fetchOffset, err = pd.getInt64(); err != nil {
  29. return err
  30. }
  31. if b.Version >= 5 {
  32. if b.logStartOffset, err = pd.getInt64(); err != nil {
  33. return err
  34. }
  35. }
  36. if b.maxBytes, err = pd.getInt32(); err != nil {
  37. return err
  38. }
  39. return nil
  40. }
  41. // FetchRequest (API key 1) will fetch Kafka messages. Version 3 introduced the MaxBytes field. See
  42. // https://issues.apache.org/jira/browse/KAFKA-2063 for a discussion of the issues leading up to that. The KIP is at
  43. // https://cwiki.apache.org/confluence/display/KAFKA/KIP-74%3A+Add+Fetch+Response+Size+Limit+in+Bytes
  44. type FetchRequest struct {
  45. MaxWaitTime int32
  46. MinBytes int32
  47. MaxBytes int32
  48. Version int16
  49. Isolation IsolationLevel
  50. SessionID int32
  51. SessionEpoch int32
  52. blocks map[string]map[int32]*fetchRequestBlock
  53. forgotten map[string][]int32
  54. RackID string
  55. }
  56. type IsolationLevel int8
  57. const (
  58. ReadUncommitted IsolationLevel = iota
  59. ReadCommitted
  60. )
  61. func (r *FetchRequest) encode(pe packetEncoder) (err error) {
  62. pe.putInt32(-1) // replica ID is always -1 for clients
  63. pe.putInt32(r.MaxWaitTime)
  64. pe.putInt32(r.MinBytes)
  65. if r.Version >= 3 {
  66. pe.putInt32(r.MaxBytes)
  67. }
  68. if r.Version >= 4 {
  69. pe.putInt8(int8(r.Isolation))
  70. }
  71. if r.Version >= 7 {
  72. pe.putInt32(r.SessionID)
  73. pe.putInt32(r.SessionEpoch)
  74. }
  75. err = pe.putArrayLength(len(r.blocks))
  76. if err != nil {
  77. return err
  78. }
  79. for topic, blocks := range r.blocks {
  80. err = pe.putString(topic)
  81. if err != nil {
  82. return err
  83. }
  84. err = pe.putArrayLength(len(blocks))
  85. if err != nil {
  86. return err
  87. }
  88. for partition, block := range blocks {
  89. pe.putInt32(partition)
  90. err = block.encode(pe, r.Version)
  91. if err != nil {
  92. return err
  93. }
  94. }
  95. }
  96. if r.Version >= 7 {
  97. err = pe.putArrayLength(len(r.forgotten))
  98. if err != nil {
  99. return err
  100. }
  101. for topic, partitions := range r.forgotten {
  102. err = pe.putString(topic)
  103. if err != nil {
  104. return err
  105. }
  106. err = pe.putArrayLength(len(partitions))
  107. if err != nil {
  108. return err
  109. }
  110. for _, partition := range partitions {
  111. pe.putInt32(partition)
  112. }
  113. }
  114. }
  115. if r.Version >= 11 {
  116. err = pe.putString(r.RackID)
  117. if err != nil {
  118. return err
  119. }
  120. }
  121. return nil
  122. }
  123. func (r *FetchRequest) decode(pd packetDecoder, version int16) (err error) {
  124. r.Version = version
  125. if _, err = pd.getInt32(); err != nil {
  126. return err
  127. }
  128. if r.MaxWaitTime, err = pd.getInt32(); err != nil {
  129. return err
  130. }
  131. if r.MinBytes, err = pd.getInt32(); err != nil {
  132. return err
  133. }
  134. if r.Version >= 3 {
  135. if r.MaxBytes, err = pd.getInt32(); err != nil {
  136. return err
  137. }
  138. }
  139. if r.Version >= 4 {
  140. isolation, err := pd.getInt8()
  141. if err != nil {
  142. return err
  143. }
  144. r.Isolation = IsolationLevel(isolation)
  145. }
  146. if r.Version >= 7 {
  147. r.SessionID, err = pd.getInt32()
  148. if err != nil {
  149. return err
  150. }
  151. r.SessionEpoch, err = pd.getInt32()
  152. if err != nil {
  153. return err
  154. }
  155. }
  156. topicCount, err := pd.getArrayLength()
  157. if err != nil {
  158. return err
  159. }
  160. if topicCount == 0 {
  161. return nil
  162. }
  163. r.blocks = make(map[string]map[int32]*fetchRequestBlock)
  164. for i := 0; i < topicCount; i++ {
  165. topic, err := pd.getString()
  166. if err != nil {
  167. return err
  168. }
  169. partitionCount, err := pd.getArrayLength()
  170. if err != nil {
  171. return err
  172. }
  173. r.blocks[topic] = make(map[int32]*fetchRequestBlock)
  174. for j := 0; j < partitionCount; j++ {
  175. partition, err := pd.getInt32()
  176. if err != nil {
  177. return err
  178. }
  179. fetchBlock := &fetchRequestBlock{}
  180. if err = fetchBlock.decode(pd, r.Version); err != nil {
  181. return err
  182. }
  183. r.blocks[topic][partition] = fetchBlock
  184. }
  185. }
  186. if r.Version >= 7 {
  187. forgottenCount, err := pd.getArrayLength()
  188. if err != nil {
  189. return err
  190. }
  191. r.forgotten = make(map[string][]int32)
  192. for i := 0; i < forgottenCount; i++ {
  193. topic, err := pd.getString()
  194. if err != nil {
  195. return err
  196. }
  197. partitionCount, err := pd.getArrayLength()
  198. if err != nil {
  199. return err
  200. }
  201. r.forgotten[topic] = make([]int32, partitionCount)
  202. for j := 0; j < partitionCount; j++ {
  203. partition, err := pd.getInt32()
  204. if err != nil {
  205. return err
  206. }
  207. r.forgotten[topic][j] = partition
  208. }
  209. }
  210. }
  211. if r.Version >= 11 {
  212. r.RackID, err = pd.getString()
  213. if err != nil {
  214. return err
  215. }
  216. }
  217. return nil
  218. }
  219. func (r *FetchRequest) key() int16 {
  220. return 1
  221. }
  222. func (r *FetchRequest) version() int16 {
  223. return r.Version
  224. }
  225. func (r *FetchRequest) requiredVersion() KafkaVersion {
  226. switch r.Version {
  227. case 0:
  228. return MinVersion
  229. case 1:
  230. return V0_9_0_0
  231. case 2:
  232. return V0_10_0_0
  233. case 3:
  234. return V0_10_1_0
  235. case 4, 5:
  236. return V0_11_0_0
  237. case 6:
  238. return V1_0_0_0
  239. case 7:
  240. return V1_1_0_0
  241. case 8:
  242. return V2_0_0_0
  243. case 9, 10:
  244. return V2_1_0_0
  245. case 11:
  246. return V2_3_0_0
  247. default:
  248. return MaxVersion
  249. }
  250. }
  251. func (r *FetchRequest) AddBlock(topic string, partitionID int32, fetchOffset int64, maxBytes int32) {
  252. if r.blocks == nil {
  253. r.blocks = make(map[string]map[int32]*fetchRequestBlock)
  254. }
  255. if r.Version >= 7 && r.forgotten == nil {
  256. r.forgotten = make(map[string][]int32)
  257. }
  258. if r.blocks[topic] == nil {
  259. r.blocks[topic] = make(map[int32]*fetchRequestBlock)
  260. }
  261. tmp := new(fetchRequestBlock)
  262. tmp.Version = r.Version
  263. tmp.maxBytes = maxBytes
  264. tmp.fetchOffset = fetchOffset
  265. if r.Version >= 9 {
  266. tmp.currentLeaderEpoch = int32(-1)
  267. }
  268. r.blocks[topic][partitionID] = tmp
  269. }