Skip to content

Commit

Permalink
[livy] Stop the python repl crashing hanging the livy-repl
Browse files Browse the repository at this point in the history
  • Loading branch information
Erick Tryzelaar committed Mar 3, 2015
1 parent c501318 commit d2568b0
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ object Session {
case class Starting() extends State
case class Idle() extends State
case class Busy() extends State
case class Error() extends State
case class ShuttingDown() extends State
case class ShutDown() extends State
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class WebApp(session: Session) extends ScalatraServlet with FutureSupport with J
case Session.Starting() => "starting"
case Session.Idle() => "idle"
case Session.Busy() => "busy"
case Session.Error() => "error"
case Session.ShuttingDown() => "shutting_down"
case Session.ShutDown() => "shut_down"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ private class PythonSession(process: Process, gatewayServer: GatewayServer) exte
private val thread = new Thread {
override def run() = {
waitUntilReady()

_state = Session.Idle()

loop()
}

Expand All @@ -132,10 +135,14 @@ private class PythonSession(process: Process, gatewayServer: GatewayServer) exte

@tailrec
def loop(): Unit = {
_state = Session.Idle()
(_state, queue.take()) match {
case (Session.Error(), ExecuteRequest(code, promise)) =>
promise.failure(new Exception("session has been terminated"))
loop()

case (state, ExecuteRequest(code, promise)) =>
require(state == Session.Idle())

queue.take() match {
case ExecuteRequest(code, promise) =>
_state = Session.Busy()

val msg = Map(
Expand All @@ -148,6 +155,7 @@ private class PythonSession(process: Process, gatewayServer: GatewayServer) exte
val line = stdout.readLine()
// The python process shut down
if (line == null) {
_state = Session.Error()
promise.failure(new Exception("session has been terminated"))
} else {
val rep = parse(line)
Expand All @@ -156,12 +164,16 @@ private class PythonSession(process: Process, gatewayServer: GatewayServer) exte
val content: JValue = rep \ "content"
_history += content

promise.success(content)
_state = Session.Idle()

loop()
promise.success(content)
}

case ShutdownRequest(promise) =>
loop()

case (_, ShutdownRequest(promise)) =>
require(state == Session.Idle() || state == Session.Error())

_state = Session.ShuttingDown()
process.getInputStream.close()
process.getOutputStream.close()
Expand Down Expand Up @@ -192,7 +204,7 @@ private class PythonSession(process: Process, gatewayServer: GatewayServer) exte
promise.future
}

override def close(): Future[Unit] = {
override def close(): Future[Unit] = synchronized {
_state match {
case Session.ShutDown() =>
Future.successful(())
Expand All @@ -202,14 +214,12 @@ private class PythonSession(process: Process, gatewayServer: GatewayServer) exte
Future.successful(())
}
case _ =>
synchronized {
val promise = Promise[Unit]()
queue.put(ShutdownRequest(promise))
promise.future.map({ case () =>
thread.join()
gatewayServer.shutdown()
})
}
val promise = Promise[Unit]()
queue.put(ShutdownRequest(promise))
promise.future.map({ case () =>
thread.join()
gatewayServer.shutdown()
})
}
}
}
Expand Down

0 comments on commit d2568b0

Please sign in to comment.