-
Notifications
You must be signed in to change notification settings - Fork 15.4k
KAFKA-10029; Don't update completedReceives when channels are closed to avoid ConcurrentModificationException #8705
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
Changes from 4 commits
74107fa
09589be
64f84b3
8cbe30e
a44db94
ceace47
d572d8e
e605e29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1597,6 +1597,8 @@ class SocketServerTest { | |
| testableSelector.waitForOperations(SelectorOperation.Poll, 1) | ||
|
|
||
| testableSelector.waitForOperations(SelectorOperation.CloseSelector, 1) | ||
| assertEquals(1, testableServer.uncaughtExceptions) | ||
| testableServer.uncaughtExceptions = 0 | ||
| }) | ||
| } | ||
|
|
||
|
|
@@ -1675,6 +1677,7 @@ class SocketServerTest { | |
| testWithServer(testableServer) | ||
| } finally { | ||
| shutdownServerAndMetrics(testableServer) | ||
| assertEquals(0, testableServer.uncaughtExceptions) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1730,6 +1733,7 @@ class SocketServerTest { | |
| new Metrics, time, credentialProvider) { | ||
|
|
||
| @volatile var selector: Option[TestableSelector] = None | ||
| @volatile var uncaughtExceptions = 0 | ||
|
|
||
| override def newProcessor(id: Int, requestChannel: RequestChannel, connectionQuotas: ConnectionQuotas, listenerName: ListenerName, | ||
| protocol: SecurityProtocol, memoryPool: MemoryPool): Processor = { | ||
|
|
@@ -1742,6 +1746,12 @@ class SocketServerTest { | |
| selector = Some(testableSelector) | ||
| testableSelector | ||
| } | ||
|
|
||
| override private[network] def processException(errorMessage: String, throwable: Throwable): Unit = { | ||
| if (errorMessage.contains("uncaught exception")) | ||
| uncaughtExceptions += 1 | ||
| super.processException(errorMessage, throwable) | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1807,6 +1817,7 @@ class SocketServerTest { | |
| currentPollValues ++= newValues | ||
| } else | ||
| deferredValues ++= newValues | ||
| newValues.clear() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the goal of this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We return
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I was asking is that we call
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, I refactored a bit to clear the original buffer in each case. |
||
| } | ||
| def reset(): Unit = { | ||
| currentPollValues.clear() | ||
|
|
@@ -1861,6 +1872,9 @@ class SocketServerTest { | |
|
|
||
| override def poll(timeout: Long): Unit = { | ||
| try { | ||
| assertEquals(0, super.completedReceives().size) | ||
| assertEquals(0, super.completedSends().size) | ||
|
|
||
| pollCallback.apply() | ||
| while (!pendingClosingChannels.isEmpty) { | ||
| makeClosing(pendingClosingChannels.poll()) | ||
|
|
@@ -1875,6 +1889,14 @@ class SocketServerTest { | |
| cachedCompletedReceives.update(super.completedReceives.asScala.toBuffer) | ||
| cachedCompletedSends.update(super.completedSends.asScala) | ||
| cachedDisconnected.update(super.disconnected.asScala.toBuffer) | ||
|
|
||
| val map: util.Map[String, NetworkReceive] = JTestUtils.fieldValue(this, classOf[Selector], "completedReceives") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we call this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ijuma Thanks for the review, updated. |
||
| cachedCompletedReceives.currentPollValues.foreach { receive => | ||
| val channelOpt = Option(super.channel(receive.source)).orElse(Option(super.closingChannel(receive.source))) | ||
| channelOpt.foreach { channel => map.put(channel.id, receive) } | ||
| } | ||
| cachedCompletedSends.currentPollValues.foreach(super.completedSends.add) | ||
| cachedDisconnected.currentPollValues.foreach { case (id, state) => super.disconnected.put(id, state) } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add a comment explaining what we're trying to do here? It's not clear why we do (for example):
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have moved the second line that updates current result into |
||
| } | ||
| } | ||
|
|
||
|
|
@@ -1899,12 +1921,6 @@ class SocketServerTest { | |
| } | ||
| } | ||
|
|
||
| override def disconnected: java.util.Map[String, ChannelState] = cachedDisconnected.currentPollValues.toMap.asJava | ||
|
|
||
| override def completedSends: java.util.List[Send] = cachedCompletedSends.currentPollValues.asJava | ||
|
|
||
| override def completedReceives: java.util.List[NetworkReceive] = cachedCompletedReceives.currentPollValues.asJava | ||
|
|
||
| override def close(id: String): Unit = { | ||
| runOp(SelectorOperation.Close, Some(id)) { | ||
| super.close(id) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: maybe
after all results have been processedis a bit redundant? Same for theclearCompletedSendsdocs.