12032: Rename permission_view and remove Rails permission cache.
[arvados.git] / services / api / app / middlewares / rack_socket.rb
index 892dbf527898b532754846722cc9de164bc612e0..1b301e27abb0f781da583780f6e071acdf9f798e 100644 (file)
@@ -1,3 +1,7 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 require 'rack'
 require 'faye/websocket'
 require 'eventmachine'
@@ -19,12 +23,13 @@ class RackSocket
   # +app+  The next layer of the Rack stack.
   #
   # Accepts options:
-  # +:handler+ (Required) A class to handle new connections.  Initialize will
+  # +:handler+ (Required) A class to handle new connections.  #initialize will
   # call handler.new to create the actual handler instance object.  When a new
   # websocket connection is established, #on_connect on the handler instance
-  # object to notify it about the connection.
+  # object will be called with the new connection.
   #
-  # +:mount+  The path for websocket connect requests, defaults to '/websocket'.
+  # +:mount+ The HTTP request path that will be recognized for websocket
+  # connect requests, defaults to '/websocket'.
   #
   # +:websocket_only+  If true, the server will only handle websocket requests,
   # and all other requests will result in an error.  If false, unhandled
@@ -43,18 +48,26 @@ class RackSocket
         if forked && EM.reactor_running?
           EM.stop
         end
-        Thread.new {
-          EM.run
-        }
+        Thread.new do
+          begin
+            EM.run
+          ensure
+            ActiveRecord::Base.connection.close
+          end
+        end
         die_gracefully_on_signal
       end
     else
       # faciliates debugging
       Thread.abort_on_exception = true
       # just spawn a thread and start it up
-      Thread.new {
-        EM.run
-      }
+      Thread.new do
+        begin
+          EM.run
+        ensure
+          ActiveRecord::Base.connection.close
+        end
+      end
     end
 
     # Create actual handler instance object from handler class.
@@ -68,7 +81,11 @@ class RackSocket
   def call env
     request = Rack::Request.new(env)
     if request.path_info == @endpoint and Faye::WebSocket.websocket?(env)
-      ws = Faye::WebSocket.new(env)
+      if @handler.overloaded?
+        return [503, {"Content-Type" => "text/plain"}, ["Too many connections, try again later."]]
+      end
+
+      ws = Faye::WebSocket.new(env, nil, :ping => 30)
 
       # Notify handler about new connection
       @handler.on_connect ws