@@ -21,13 +21,14 @@ import java.io.{DataOutputStream, FileNotFoundException}
2121import java .net .{ConnectException , HttpURLConnection , SocketException , URL }
2222import javax .servlet .http .HttpServletResponse
2323
24+ import scala .collection .mutable
2425import scala .io .Source
2526
2627import com .fasterxml .jackson .core .JsonProcessingException
2728import com .google .common .base .Charsets
2829
2930import org .apache .spark .{Logging , SparkConf , SPARK_VERSION => sparkVersion }
30- import scala . collection . mutable
31+ import org . apache . spark . util . Utils
3132
3233/**
3334 * A client that submits applications to the standalone Master using a REST protocol.
@@ -52,11 +53,14 @@ import scala.collection.mutable
5253 * is a mismatch, the server will respond with the highest protocol version it supports. A future
5354 * implementation of this client can use that information to retry using the version specified
5455 * by the server.
56+ *
57+ * Now we don't support retry in case submission failed. In HA mode, client will submit request to
58+ * all masters and see which one could handle it.
5559 */
5660private [deploy] class StandaloneRestClient (master : String ) extends Logging {
5761 import StandaloneRestClient ._
5862
59- val masters : Array [String ] = master.stripPrefix( " spark:// " ).split( " , " ).map( " spark:// " + _ )
63+ private val masters : Array [String ] = Utils .splitMasterAdress(master )
6064
6165 private val lostMasters = new mutable.HashSet [String ]
6266
@@ -87,10 +91,15 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
8791 handleUnexpectedRestResponse(unexpected)
8892 }
8993 } catch {
90- case e @ (_ : SubmitRestConnectionException | _ : ConnectException ) =>
91- if (handleSubmitRestConnectionException (m)) {
94+ case unreachable @ (_ : FileNotFoundException | _ : SocketException | _ : ConnectException ) =>
95+ if (handleConnectionException (m)) {
9296 throw new SubmitRestConnectionException (
93- " No master is available for createSubmission." , new Throwable (" " ))
97+ s " Unable to connect to server " , unreachable)
98+ }
99+ case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
100+ if (handleConnectionException(m)) {
101+ throw new SubmitRestProtocolException (
102+ " Malformed response received from server" , malformed)
94103 }
95104 }
96105 }
@@ -109,18 +118,23 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
109118 response = post(url)
110119 response match {
111120 case k : KillSubmissionResponse =>
112- if (! k.message.contains( " Can only " )) {
121+ if (! k.message.startsWith( Utils . MASTER_NOT_ALIVE_STRING )) {
113122 handleRestResponse(k)
114123 suc = true
115124 }
116125 case unexpected =>
117126 handleUnexpectedRestResponse(unexpected)
118127 }
119128 } catch {
120- case e @ (_ : SubmitRestConnectionException | _ : ConnectException ) =>
121- if (handleSubmitRestConnectionException (m)) {
129+ case unreachable @ (_ : FileNotFoundException | _ : SocketException | _ : ConnectException ) =>
130+ if (handleConnectionException (m)) {
122131 throw new SubmitRestConnectionException (
123- " No master is available for killSubmission." , new Throwable (" " ))
132+ s " Unable to connect to server " , unreachable)
133+ }
134+ case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
135+ if (handleConnectionException(m)) {
136+ throw new SubmitRestProtocolException (
137+ " Malformed response received from server" , malformed)
124138 }
125139 }
126140 }
@@ -149,10 +163,15 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
149163 handleUnexpectedRestResponse(unexpected)
150164 }
151165 } catch {
152- case e @ (_ : SubmitRestConnectionException | _ : ConnectException ) =>
153- if (handleSubmitRestConnectionException (m)) {
166+ case unreachable @ (_ : FileNotFoundException | _ : SocketException | _ : ConnectException ) =>
167+ if (handleConnectionException (m)) {
154168 throw new SubmitRestConnectionException (
155- " No master is available for requestSubmissionStatus." , new Throwable (" " ))
169+ s " Unable to connect to server " , unreachable)
170+ }
171+ case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
172+ if (handleConnectionException(m)) {
173+ throw new SubmitRestProtocolException (
174+ " Malformed response received from server" , malformed)
156175 }
157176 }
158177 }
@@ -213,39 +232,30 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
213232 * Exposed for testing.
214233 */
215234 private [rest] def readResponse (connection : HttpURLConnection ): SubmitRestProtocolResponse = {
216- try {
217- val dataStream =
218- if (connection.getResponseCode == HttpServletResponse .SC_OK ) {
219- connection.getInputStream
220- } else {
221- connection.getErrorStream
222- }
223- // If the server threw an exception while writing a response, it will not have a body
224- if (dataStream == null ) {
225- throw new SubmitRestProtocolException (" Server returned empty body" )
226- }
227- val responseJson = Source .fromInputStream(dataStream).mkString
228- logDebug(s " Response from the server: \n $responseJson" )
229- val response = SubmitRestProtocolMessage .fromJson(responseJson)
230- response.validate()
231- response match {
232- // If the response is an error, log the message
233- case error : ErrorResponse =>
234- logError(s " Server responded with error: \n ${error.message}" )
235- error
236- // Otherwise, simply return the response
237- case response : SubmitRestProtocolResponse => response
238- case unexpected =>
239- throw new SubmitRestProtocolException (
240- s " Message received from server was not a response: \n ${unexpected.toJson}" )
235+ val dataStream =
236+ if (connection.getResponseCode == HttpServletResponse .SC_OK ) {
237+ connection.getInputStream
238+ } else {
239+ connection.getErrorStream
241240 }
242- } catch {
243- case unreachable @ (_ : FileNotFoundException | _ : SocketException ) =>
244- throw new SubmitRestConnectionException (
245- s " Unable to connect to server ${connection.getURL}" , unreachable)
246- case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
241+ // If the server threw an exception while writing a response, it will not have a body
242+ if (dataStream == null ) {
243+ throw new SubmitRestProtocolException (" Server returned empty body" )
244+ }
245+ val responseJson = Source .fromInputStream(dataStream).mkString
246+ logDebug(s " Response from the server: \n $responseJson" )
247+ val response = SubmitRestProtocolMessage .fromJson(responseJson)
248+ response.validate()
249+ response match {
250+ // If the response is an error, log the message
251+ case error : ErrorResponse =>
252+ logError(s " Server responded with error: \n ${error.message}" )
253+ error
254+ // Otherwise, simply return the response
255+ case response : SubmitRestProtocolResponse => response
256+ case unexpected =>
247257 throw new SubmitRestProtocolException (
248- " Malformed response received from server" , malformed )
258+ s " Message received from server was not a response: \n ${unexpected.toJson} " )
249259 }
250260 }
251261
@@ -338,10 +348,13 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
338348 logError(s " Error: Server responded with message of unexpected type ${unexpected.messageType}. " )
339349 }
340350
341- private def handleSubmitRestConnectionException (url : String ): Boolean = {
342- if (! lostMasters.contains(url)) {
343- logWarning(s " Unable to connect to server ${url}. " )
344- lostMasters += url
351+ /**
352+ * When a connection exception was caught, we see whether all masters are lost.
353+ */
354+ private def handleConnectionException (masterUrl : String ): Boolean = {
355+ if (! lostMasters.contains(masterUrl)) {
356+ logWarning(s " Unable to connect to server ${masterUrl}. " )
357+ lostMasters += masterUrl
345358 }
346359 lostMasters.size >= masters.size
347360 }
0 commit comments