Skip to content

Commit 1d7e408

Browse files
committed
Treat 0 ports specially + return correct ConnectionManager port
1 parent ba32280 commit 1d7e408

File tree

3 files changed

+20
-23
lines changed

3 files changed

+20
-23
lines changed

core/src/main/scala/org/apache/spark/network/ConnectionManager.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private[spark] class ConnectionManager(
110110

111111
private def startService(port: Int): (ServerSocketChannel, Int) = {
112112
serverChannel.socket.bind(new InetSocketAddress(port))
113-
(serverChannel, port)
113+
(serverChannel, serverChannel.socket.getLocalPort)
114114
}
115115
Utils.startServiceOnPort[ServerSocketChannel](port, startService, name)
116116
serverChannel.register(selector, SelectionKey.OP_ACCEPT)

core/src/main/scala/org/apache/spark/ui/JettyUtils.scala

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -174,40 +174,33 @@ private[spark] object JettyUtils extends Logging {
174174
hostName: String,
175175
port: Int,
176176
handlers: Seq[ServletContextHandler],
177-
conf: SparkConf): ServerInfo = {
177+
conf: SparkConf,
178+
serverName: String = ""): ServerInfo = {
178179

179180
val collection = new ContextHandlerCollection
180181
collection.setHandlers(handlers.toArray)
181182
addFilters(handlers, conf)
182183

183-
@tailrec
184+
// Bind to the given port, or throw a java.net.BindException if the port is occupied
184185
def connect(currentPort: Int): (Server, Int) = {
185186
val server = new Server(new InetSocketAddress(hostName, currentPort))
186187
val pool = new QueuedThreadPool
187188
pool.setDaemon(true)
188189
server.setThreadPool(pool)
189190
server.setHandler(collection)
190-
191-
Try {
191+
try {
192192
server.start()
193-
} match {
194-
case s: Success[_] =>
195-
(server, server.getConnectors.head.getLocalPort)
196-
case f: Failure[_] =>
197-
val nextPort = (currentPort + 1) % 65536
193+
(server, server.getConnectors.head.getLocalPort)
194+
} catch {
195+
case e: Exception =>
198196
server.stop()
199197
pool.stop()
200-
val msg = s"Failed to create UI on port $currentPort. Trying again on port $nextPort."
201-
if (f.toString.contains("Address already in use")) {
202-
logWarning(s"$msg - $f")
203-
} else {
204-
logError(msg, f.exception)
205-
}
206-
connect(nextPort)
198+
throw e
207199
}
208200
}
209201

210-
val (server, boundPort) = connect(port)
202+
val (server, boundPort) =
203+
Utils.startServiceOnPort[Server](port, connect, serverName, maxRetries = 10)
211204
ServerInfo(server, boundPort, collection)
212205
}
213206

core/src/main/scala/org/apache/spark/util/Utils.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,22 +1347,26 @@ private[spark] object Utils extends Logging {
13471347
startService: Int => (T, Int),
13481348
serviceName: String = "",
13491349
maxRetries: Int = 3): (T, Int) = {
1350+
val serviceString = if (serviceName.isEmpty) "" else s" '$serviceName'"
13501351
for (offset <- 0 to maxRetries) {
1351-
val tryPort = (startPort + offset) % 65536
1352+
// Do not increment port if startPort is 0, which is treated as a special port
1353+
val tryPort = if (startPort == 0) startPort else (startPort + offset) % 65536
13521354
try {
1353-
return startService(tryPort)
1355+
val (service, port) = startService(tryPort)
1356+
logInfo(s"Successfully started service$serviceString on port $port.")
1357+
return (service, port)
13541358
} catch {
13551359
case e: BindException =>
1356-
val service = if (serviceName.isEmpty) "Service" else s"Service '$serviceName'"
13571360
if (!e.getMessage.contains("Address already in use") || offset >= maxRetries) {
13581361
val exceptionMessage =
1359-
s"${e.getMessage}: $service failed after $maxRetries retries!"
1362+
s"${e.getMessage}: Service$serviceString failed after $maxRetries retries!"
13601363
val exception = new BindException(exceptionMessage)
13611364
// restore original stack trace
13621365
exception.setStackTrace(e.getStackTrace)
13631366
throw exception
13641367
}
1365-
logInfo(s"$service could not bind on port $tryPort. Attempting port ${tryPort + 1}.")
1368+
logWarning(s"Service$serviceString could not bind on port $tryPort. " +
1369+
s"Attempting port ${tryPort + 1}.")
13661370
}
13671371
}
13681372
// Should never happen

0 commit comments

Comments
 (0)