Repository: incubator-livy
Updated Branches:
  refs/heads/master 4cfb6bcb8 -> 8504c641e


[LIVY-535] Fix non-atomic session creation

## What changes were proposed in this pull request?

All steps, that include check for too many sessions and creating new
session, should be atomic operation to avoid concurrent access of
several threads to different part of this code in the same time.

https://issues.apache.org/jira/browse/LIVY-535

## How was this patch tested?
If was tested manually on local virtual cluster with this different values of 
config option `livy.server.session.max-creation`: 1, 2 and 3

Then I run the following command to make sure that only allowed number of 
sessions were created in the same time and others were rejected:
`for i in {1..5}; do curl -X POST --data '{"file": "/tmp/spark-examples-2.jar", 
"className": "org.apache.spark.examples.SparkPi"}' -H "Content-Type: 
application/json" http://localhost:8999/batches; done`

Author: Alexey Romanenko <aromanenko....@gmail.com>

Closes #129 from aromanenko-dev/LIVY-535-session-max-creation.


Project: http://git-wip-us.apache.org/repos/asf/incubator-livy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-livy/commit/8504c641
Tree: http://git-wip-us.apache.org/repos/asf/incubator-livy/tree/8504c641
Diff: http://git-wip-us.apache.org/repos/asf/incubator-livy/diff/8504c641

Branch: refs/heads/master
Commit: 8504c641eae91473f0c112d7438def489484619d
Parents: 4cfb6bc
Author: Alexey Romanenko <aromanenko....@gmail.com>
Authored: Mon Nov 26 09:21:09 2018 -0800
Committer: Marcelo Vanzin <van...@cloudera.com>
Committed: Mon Nov 26 09:21:09 2018 -0800

----------------------------------------------------------------------
 .../org/apache/livy/server/SessionServlet.scala | 22 +++++++++++---------
 1 file changed, 12 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-livy/blob/8504c641/server/src/main/scala/org/apache/livy/server/SessionServlet.scala
----------------------------------------------------------------------
diff --git a/server/src/main/scala/org/apache/livy/server/SessionServlet.scala 
b/server/src/main/scala/org/apache/livy/server/SessionServlet.scala
index f7547c5..d62a96e 100644
--- a/server/src/main/scala/org/apache/livy/server/SessionServlet.scala
+++ b/server/src/main/scala/org/apache/livy/server/SessionServlet.scala
@@ -127,16 +127,18 @@ abstract class SessionServlet[S <: Session, R <: 
RecoveryMetadata](
   }
 
   post("/") {
-    if (tooManySessions) {
-      BadRequest(ResponseMessage("Rejected, too many sessions are being 
created!"))
-    } else {
-      val session = sessionManager.register(createSession(request))
-      // Because it may take some time to establish the session, update the 
last activity
-      // time before returning the session info to the client.
-      session.recordActivity()
-      Created(clientSessionView(session, request),
-        headers = Map("Location" ->
-          (getRequestPathInfo(request) + url(getSession, "id" -> 
session.id.toString))))
+    synchronized {
+      if (tooManySessions) {
+        BadRequest(ResponseMessage("Rejected, too many sessions are being 
created!"))
+      } else {
+        val session = sessionManager.register(createSession(request))
+        // Because it may take some time to establish the session, update the 
last activity
+        // time before returning the session info to the client.
+        session.recordActivity()
+        Created(clientSessionView(session, request),
+          headers = Map("Location" ->
+            (getRequestPathInfo(request) + url(getSession, "id" -> 
session.id.toString))))
+      }
     }
   }
 

Reply via email to