@@ -53,15 +53,14 @@ import org.apache.spark.util.Utils
53
53
* is a mismatch, the server will respond with the highest protocol version it supports. A future
54
54
* implementation of this client can use that information to retry using the version specified
55
55
* 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.
59
56
*/
60
57
private [deploy] class StandaloneRestClient (master : String ) extends Logging {
61
58
import StandaloneRestClient ._
62
59
63
- private val masters : Array [String ] = Utils .splitMasterAdress (master)
60
+ private val masters : Array [String ] = Utils .parseStandaloneMasterUrls (master)
64
61
62
+ // Set of masters that lost contact with us, used to keep track of
63
+ // whether there are masters still alive for us to communicate with
65
64
private val lostMasters = new mutable.HashSet [String ]
66
65
67
66
/**
@@ -73,9 +72,9 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
73
72
private [rest] def createSubmission (
74
73
request : CreateSubmissionRequest ): SubmitRestProtocolResponse = {
75
74
logInfo(s " Submitting a request to launch an application in $master. " )
76
- var suc : Boolean = false
75
+ var handled : Boolean = false
77
76
var response : SubmitRestProtocolResponse = null
78
- for (m <- masters if ! suc ) {
77
+ for (m <- masters if ! handled ) {
79
78
validateMaster(m)
80
79
val url = getSubmitUrl(m)
81
80
try {
@@ -85,22 +84,17 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
85
84
if (s.success) {
86
85
reportSubmissionStatus(s)
87
86
handleRestResponse(s)
88
- suc = true
87
+ handled = true
89
88
}
90
89
case unexpected =>
91
90
handleUnexpectedRestResponse(unexpected)
92
91
}
93
92
} catch {
94
93
case unreachable @ (_ : FileNotFoundException | _ : SocketException | _ : ConnectException ) =>
95
- if (handleConnectionException(m)) {
94
+ if (handleConnectionException(m)) {
96
95
throw new SubmitRestConnectionException (
97
96
s " Unable to connect to server " , unreachable)
98
97
}
99
- case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
100
- if (handleConnectionException(m)) {
101
- throw new SubmitRestProtocolException (
102
- " Malformed response received from server" , malformed)
103
- }
104
98
}
105
99
}
106
100
response
@@ -109,33 +103,28 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
109
103
/** Request that the server kill the specified submission. */
110
104
def killSubmission (submissionId : String ): SubmitRestProtocolResponse = {
111
105
logInfo(s " Submitting a request to kill submission $submissionId in $master. " )
112
- var suc : Boolean = false
106
+ var handled : Boolean = false
113
107
var response : SubmitRestProtocolResponse = null
114
- for (m <- masters if ! suc ) {
108
+ for (m <- masters if ! handled ) {
115
109
validateMaster(m)
116
110
val url = getKillUrl(m, submissionId)
117
111
try {
118
112
response = post(url)
119
113
response match {
120
114
case k : KillSubmissionResponse =>
121
- if (! k.message.startsWith( Utils . MASTER_NOT_ALIVE_STRING )) {
115
+ if (! Utils .responseFromBackup(k.message )) {
122
116
handleRestResponse(k)
123
- suc = true
117
+ handled = true
124
118
}
125
119
case unexpected =>
126
120
handleUnexpectedRestResponse(unexpected)
127
121
}
128
122
} catch {
129
123
case unreachable @ (_ : FileNotFoundException | _ : SocketException | _ : ConnectException ) =>
130
- if (handleConnectionException(m)) {
124
+ if (handleConnectionException(m)) {
131
125
throw new SubmitRestConnectionException (
132
126
s " Unable to connect to server " , unreachable)
133
127
}
134
- case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
135
- if (handleConnectionException(m)) {
136
- throw new SubmitRestProtocolException (
137
- " Malformed response received from server" , malformed)
138
- }
139
128
}
140
129
}
141
130
response
@@ -146,9 +135,9 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
146
135
submissionId : String ,
147
136
quiet : Boolean = false ): SubmitRestProtocolResponse = {
148
137
logInfo(s " Submitting a request for the status of submission $submissionId in $master. " )
149
- var suc : Boolean = false
138
+ var handled : Boolean = false
150
139
var response : SubmitRestProtocolResponse = null
151
- for (m <- masters) {
140
+ for (m <- masters if ! handled ) {
152
141
validateMaster(m)
153
142
val url = getStatusUrl(m, submissionId)
154
143
try {
@@ -158,21 +147,16 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
158
147
if (! quiet) {
159
148
handleRestResponse(s)
160
149
}
161
- suc = true
150
+ handled = true
162
151
case unexpected =>
163
152
handleUnexpectedRestResponse(unexpected)
164
153
}
165
154
} catch {
166
155
case unreachable @ (_ : FileNotFoundException | _ : SocketException | _ : ConnectException ) =>
167
- if (handleConnectionException(m)) {
156
+ if (handleConnectionException(m)) {
168
157
throw new SubmitRestConnectionException (
169
158
s " Unable to connect to server " , unreachable)
170
159
}
171
- case malformed @ (_ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
172
- if (handleConnectionException(m)) {
173
- throw new SubmitRestProtocolException (
174
- " Malformed response received from server" , malformed)
175
- }
176
160
}
177
161
}
178
162
response
@@ -235,30 +219,35 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
235
219
* Exposed for testing.
236
220
*/
237
221
private [rest] def readResponse (connection : HttpURLConnection ): SubmitRestProtocolResponse = {
238
- val dataStream =
239
- if (connection.getResponseCode == HttpServletResponse .SC_OK ) {
240
- connection.getInputStream
241
- } else {
242
- connection.getErrorStream
222
+ try {
223
+ val dataStream =
224
+ if (connection.getResponseCode == HttpServletResponse .SC_OK ) {
225
+ connection.getInputStream
226
+ } else {
227
+ connection.getErrorStream
228
+ }
229
+ // If the server threw an exception while writing a response, it will not have a body
230
+ if (dataStream == null ) {
231
+ throw new SubmitRestProtocolException (" Server returned empty body" )
243
232
}
244
- // If the server threw an exception while writing a response, it will not have a body
245
- if (dataStream == null ) {
246
- throw new SubmitRestProtocolException ( " Server returned empty body " )
247
- }
248
- val responseJson = Source .fromInputStream(dataStream).mkString
249
- logDebug( s " Response from the server: \n $responseJson " )
250
- val response = SubmitRestProtocolMessage .fromJson(responseJson)
251
- response.validate( )
252
- response match {
253
- // If the response is an error, log the message
254
- case error : ErrorResponse =>
255
- logError( s " Server responded with error: \n ${error.message} " )
256
- error
257
- // Otherwise, simply return the response
258
- case response : SubmitRestProtocolResponse => response
259
- case unexpected =>
260
- throw new SubmitRestProtocolException (
261
- s " Message received from server was not a response: \n ${unexpected.toJson} " )
233
+ val responseJson = Source .fromInputStream(dataStream).mkString
234
+ logDebug( s " Response from the server: \n $responseJson " )
235
+ val response = SubmitRestProtocolMessage .fromJson(responseJson )
236
+ response.validate()
237
+ response match {
238
+ // If the response is an error, log the message
239
+ case error : ErrorResponse =>
240
+ logError( s " Server responded with error: \n ${error.message} " )
241
+ error
242
+ // Otherwise, simply return the response
243
+ case response : SubmitRestProtocolResponse => response
244
+ case unexpected =>
245
+ throw new SubmitRestProtocolException (
246
+ s " Message received from server was not a response: \n ${unexpected.toJson} " )
247
+ }
248
+ } catch {
249
+ case malformed @ ( _ : JsonProcessingException | _ : SubmitRestProtocolException ) =>
250
+ throw new SubmitRestProtocolException ( " Malformed response received from server" , malformed )
262
251
}
263
252
}
264
253
@@ -357,7 +346,11 @@ private[deploy] class StandaloneRestClient(master: String) extends Logging {
357
346
}
358
347
359
348
/**
360
- * When a connection exception was caught, we see whether all masters are lost.
349
+ * When a connection exception is caught, return true if all masters are lost.
350
+ * Note that the heuristic used here does not take into account that masters
351
+ * can recover during the lifetime of this client. This assumption should be
352
+ * harmless because this client currently does not support retrying submission
353
+ * on failure yet (SPARK-6443).
361
354
*/
362
355
private def handleConnectionException (masterUrl : String ): Boolean = {
363
356
if (! lostMasters.contains(masterUrl)) {
0 commit comments