Skip to content

Commit 6f86a56

Browse files
authored
Merge pull request #63 from tulios/undefined-partitions-on-produce-retry-#62
Prevent crash when re-producing after metadata refresh
2 parents 4d71d3d + d5b3dfc commit 6f86a56

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.1] - 2018-05-18
9+
### Fixed
10+
- Prevent crash when re-producing after metadata refresh #62
11+
812
## [1.0.0] - 2018-05-14
913
## Changed
1014
- Updated readme

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "kafkajs",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "A modern Apache Kafka client for node.js",
55
"author": "Tulio Ornelas <[email protected]>",
66
"main": "index.js",

src/producer/sendMessages.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,13 @@ module.exports = ({ logger, cluster, partitioner }) => {
4545
const partitions = partitionsPerLeader[broker.nodeId]
4646
const topicData = createTopicData({ topic, partitions, messagesPerPartition })
4747

48-
const response = await broker.produce({ acks, timeout, compression, topicData })
49-
responsePerBroker.set(broker, responseSerializer(response))
48+
try {
49+
const response = await broker.produce({ acks, timeout, compression, topicData })
50+
responsePerBroker.set(broker, responseSerializer(response))
51+
} catch (e) {
52+
responsePerBroker.delete(broker)
53+
throw e
54+
}
5055
})
5156
}
5257

src/producer/sendMessages.spec.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('Producer > sendMessages', () => {
3535
1: { nodeId: 1, produce: jest.fn(() => createProducerResponse(topic, 0)) },
3636
2: { nodeId: 2, produce: jest.fn(() => createProducerResponse(topic, 1)) },
3737
3: { nodeId: 3, produce: jest.fn(() => createProducerResponse(topic, 2)) },
38+
4: { nodeId: 4, produce: jest.fn(() => createProducerResponse(topic, 1)) },
3839
}
3940
cluster = {
4041
addTargetTopic: jest.fn(),
@@ -75,8 +76,8 @@ describe('Producer > sendMessages', () => {
7576
expect(brokers[2].produce).toHaveBeenCalledTimes(1)
7677
expect(brokers[3].produce).toHaveBeenCalledTimes(3)
7778
expect(response).toEqual([
78-
{ errorCode: 0, offset: '0', partition: 0, timestamp: '-1', topicName: 'topic-name' },
7979
{ errorCode: 0, offset: '1', partition: 1, timestamp: '-1', topicName: 'topic-name' },
80+
{ errorCode: 0, offset: '0', partition: 0, timestamp: '-1', topicName: 'topic-name' },
8081
{ errorCode: 0, offset: '2', partition: 2, timestamp: '-1', topicName: 'topic-name' },
8182
])
8283
})
@@ -108,4 +109,31 @@ describe('Producer > sendMessages', () => {
108109
expect(cluster.refreshMetadata).toHaveBeenCalled()
109110
})
110111
}
112+
113+
test('does not re-produce messages to brokers that are no longer leaders after metadata refresh', async () => {
114+
const sendMessages = createSendMessages({ logger: newLogger(), cluster, partitioner })
115+
116+
brokers[2].produce
117+
.mockImplementationOnce(() => {
118+
const e = new Error('Some error broker 1')
119+
e.type = 'NOT_LEADER_FOR_PARTITION'
120+
throw e
121+
})
122+
.mockImplementationOnce(() => createProducerResponse(topic, 0))
123+
cluster.findLeaderForPartitions
124+
.mockImplementationOnce(() => partitionsPerLeader)
125+
.mockImplementationOnce(() => ({
126+
1: [0],
127+
4: [1], // Broker 4 replaces broker 2 as leader for partition 1
128+
3: [2],
129+
}))
130+
131+
const response = await sendMessages({ topic, messages })
132+
133+
expect(response).toEqual([
134+
{ errorCode: 0, offset: '0', partition: 0, timestamp: '-1', topicName: 'topic-name' },
135+
{ errorCode: 0, offset: '2', partition: 2, timestamp: '-1', topicName: 'topic-name' },
136+
{ errorCode: 0, offset: '1', partition: 1, timestamp: '-1', topicName: 'topic-name' },
137+
])
138+
})
111139
})

0 commit comments

Comments
 (0)