@@ -4,7 +4,7 @@ import java.util.NoSuchElementException
4
4
import java .util .concurrent .TimeUnit
5
5
import javax .net .ssl .SSLContext
6
6
7
- import akka .actor .{Actor , ActorLogging , ActorRef , ActorSystem , Props }
7
+ import akka .actor .{ActorRef , ActorSystem }
8
8
import akka .pattern .ask
9
9
import akka .util .Timeout
10
10
import com .typesafe .config .{Config , ConfigException , ConfigFactory , ConfigRenderOptions }
@@ -18,7 +18,6 @@ import spark.jobserver.auth._
18
18
import spark .jobserver .io .JobInfo
19
19
import spark .jobserver .routes .DataRoutes
20
20
import spark .jobserver .util .{SSLContextFactory , SparkJobUtils }
21
- import spray .can .Http
22
21
import spray .http ._
23
22
import spray .httpx .SprayJsonSupport .sprayJsonMarshaller
24
23
import spray .io .ServerSSLEngineProvider
@@ -106,7 +105,8 @@ class WebApi(system: ActorSystem,
106
105
dataManager : ActorRef ,
107
106
supervisor : ActorRef ,
108
107
jobInfo : ActorRef )
109
- extends HttpService with CommonRoutes with DataRoutes with SJSAuthenticator with CORSSupport {
108
+ extends HttpService with CommonRoutes with DataRoutes with SJSAuthenticator with CORSSupport
109
+ with ChunkEncodedStreamingSupport {
110
110
import CommonMessages ._
111
111
import ContextSupervisor ._
112
112
import scala .concurrent .duration ._
@@ -123,12 +123,8 @@ class WebApi(system: ActorSystem,
123
123
val DefaultJobLimit = 50
124
124
val StatusKey = " status"
125
125
val ResultKey = " result"
126
- val ResultChunkSize = if (config.hasPath(" spark.jobserver.result-chunk-size" )) {
127
- config.getBytes(" spark.jobserver.result-chunk-size" ).toInt
128
- }
129
- else {
130
- 100 * 1024
131
- }
126
+ val ResultChunkSize = Option (" spark.jobserver.result-chunk-size" ).filter(config.hasPath)
127
+ .fold(100 * 1024 )(config.getBytes(_).toInt)
132
128
133
129
val contextTimeout = SparkJobUtils .getContextTimeout(config)
134
130
val bindAddress = config.getString(" spark.jobserver.bind-address" )
@@ -489,13 +485,12 @@ class WebApi(system: ActorSystem,
489
485
JobManagerActor .StartJob (appName, classPath, jobConfig, events))(timeout)
490
486
respondWithMediaType(MediaTypes .`application/json`) { ctx =>
491
487
future.map {
492
- case JobResult (_, res) => {
488
+ case JobResult (_, res) =>
493
489
res match {
494
490
case s : Stream [_] => sendStreamingResponse(ctx, ResultChunkSize ,
495
491
resultToByteIterator(Map .empty, s.toIterator))
496
492
case _ => ctx.complete(resultToTable(res))
497
493
}
498
- }
499
494
case JobErroredOut (_, _, ex) => ctx.complete(errMap(ex, " ERROR" ))
500
495
case JobStarted (jobId, context, _) =>
501
496
jobInfo ! StoreJobConfig (jobId, postedJobConfig)
@@ -533,43 +528,6 @@ class WebApi(system: ActorSystem,
533
528
}
534
529
}
535
530
536
- private def sendStreamingResponse (ctx : RequestContext ,
537
- chunkSize : Int ,
538
- byteIterator : Iterator [_]): Unit = {
539
- // simple case class whose instances we use as send confirmation message for streaming chunks
540
- case class Ok (remaining : Iterator [_])
541
- actorRefFactory.actorOf {
542
- Props {
543
- new Actor with ActorLogging {
544
- // we use the successful sending of a chunk as trigger for sending the next chunk
545
- ctx.responder ! ChunkedResponseStart (
546
- HttpResponse (entity = HttpEntity (MediaTypes .`application/json`,
547
- byteIterator.take(chunkSize).map {
548
- case c : Byte => c
549
- }.toArray))).withAck(Ok (byteIterator))
550
-
551
- def receive : Receive = {
552
- case Ok (remaining) =>
553
- val arr = remaining.take(chunkSize).map {
554
- case c : Byte => c
555
- }.toArray
556
- if (arr.nonEmpty) {
557
- ctx.responder ! MessageChunk (arr).withAck(Ok (remaining))
558
- }
559
- else {
560
- ctx.responder ! ChunkedMessageEnd
561
- context.stop(self)
562
- }
563
- case ev : Http .ConnectionClosed => {
564
- log.warning(" Stopping response streaming due to {}" , ev)
565
- context.stop(self)
566
- }
567
- }
568
- }
569
- }
570
- }
571
- }
572
-
573
531
override def timeoutRoute : Route =
574
532
complete(500 , errMap(" Request timed out. Try using the /jobs/<jobID>, /jobs APIs to get status/results" ))
575
533
0 commit comments