[ARVADOS] created: 715402a5f0ece5c2e16b47cef8d20011bdecf6f1

git at public.curoverse.com git at public.curoverse.com
Mon Apr 21 16:43:21 EDT 2014


        at  715402a5f0ece5c2e16b47cef8d20011bdecf6f1 (commit)


commit 715402a5f0ece5c2e16b47cef8d20011bdecf6f1
Author: Peter Amstutz <tetron at arvados-dev>
Date:   Mon Apr 21 16:36:15 2014 -0400

    Seems to finally be doing the right thing with background threads pushing
    events into the EventMachine channel.

diff --git a/services/api/app/middlewares/rack_socket.rb b/services/api/app/middlewares/rack_socket.rb
index 7fcba83..181cdf6 100644
--- a/services/api/app/middlewares/rack_socket.rb
+++ b/services/api/app/middlewares/rack_socket.rb
@@ -1,38 +1,86 @@
+require 'rack'
+require 'faye/websocket'
+require 'oj'
+require 'eventmachine'
 
-  require 'faye/websocket'
+class RackSocket
 
-  class RackSocket
+  DEFAULT_ENDPOINT  = '/websocket'
 
-    DEFAULT_ENDPOINT  = '/websocket'
+  def die_gracefully_on_signal
+    Signal.trap("INT") { EM.stop }
+    Signal.trap("TERM") { EM.stop }
+  end
+
+  def initialize(app = nil, options = nil)
+    @app = app if app.respond_to?(:call)
+    @options = [app, options].grep(Hash).first || {}
+    @endpoint = @options[:mount] || DEFAULT_ENDPOINT
 
-    def initialize(app = nil, options = nil)
-      @app = app if app.respond_to?(:call)
-      @options = [app, options].grep(Hash).first || {}
-      @endpoint = @options[:mount] || DEFAULT_ENDPOINT
+    # from https://gist.github.com/eatenbyagrue/1338545#file-eventmachine-rb
+    if defined?(PhusionPassenger)
+      PhusionPassenger.on_event(:starting_worker_process) do |forked|
+        # for passenger, we need to avoid orphaned threads
+        if forked && EM.reactor_running?
+          EM.stop
+        end
+        Thread.new {
+          EM.run
+        }
+        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
+      }
     end
 
-    def call env
-      request = Rack::Request.new(env)
-      if request.path_info == @endpoint and Faye::WebSocket.websocket?(env)
-        ws = Faye::WebSocket.new(env)
+    @channel = EventMachine::Channel.new
+    @bgthread = nil
+  end
 
-        ws.on :message do |event|
-          puts "got #{event.data}"
-          ws.send(event.data)
-        end
+  def call env
+    request = Rack::Request.new(env)
+    if request.path_info == @endpoint and Faye::WebSocket.websocket?(env)
+      ws = Faye::WebSocket.new(env)
 
-        ws.on :close do |event|
-          p [:close, event.code, event.reason]
-          ws = nil
-        end
+      sub = @channel.subscribe do |msg|
+        puts "sending #{msg}"
+        ws.send({:message => "log"}.to_json)
+      end
 
-        # Return async Rack response
-        ws.rack_response
-      else
-        @app.call env
+      ws.on :message do |event|
+        puts "got #{event.data}"
+        ws.send(event.data)
+      end
+
+      ws.on :close do |event|
+        p [:close, event.code, event.reason]
+        @channel.unsubscribe sub
+        ws = nil
+      end
+
+      unless @bgthread
+        @bgthread = true
+        Thread.new do
+          while true
+            sleep 3
+            puts "pushing"
+            @channel.push true
+          end
+        end
       end
-    end
 
+      # Return async Rack response
+      ws.rack_response
+    else
+      @app.call env
+    end
   end
 
+end
+
 

commit c283713dc8762c396407f68129fb276dc4a746fc
Author: Peter Amstutz <tetron at arvados-dev>
Date:   Mon Apr 21 14:28:33 2014 -0400

    Proof of concept echo server based on rack middleware that hijacks websocket connections.

diff --git a/apps/workbench/app/views/websocket/index.html.erb b/apps/workbench/app/views/websocket/index.html.erb
index d4259a9..e1fca78 100644
--- a/apps/workbench/app/views/websocket/index.html.erb
+++ b/apps/workbench/app/views/websocket/index.html.erb
@@ -4,7 +4,6 @@
 <h1>Event bus debugging page</h1>
 
 <form>
-<input type="text" style="width:100%" id="websocket-message-type">
 <textarea style="width:100%; height: 10em" id="websocket-message-content"></textarea>
 <button type="button" id="send-to-websocket">Send</button>
 </form>
@@ -19,11 +18,13 @@ putStuffThere = function (content) {
   $("#PutStuffHere").append(content["message"] + "<br>");
 };
 
-var dispatcher = new WebSocketRails('localhost:3032/arvados/v1/events?api_token=<%= Thread.current[:arvados_api_token] %>');
-dispatcher.bind('hello', putStuffThere);
+var dispatcher = new WebSocket('ws://localhost:3001/websocket?api_token=<%= Thread.current[:arvados_api_token] %>');
+dispatcher.onmessage = function(event) {
+  putStuffThere(JSON.parse(event.data));
+};
 
 sendStuff = function () {
-  dispatcher.trigger($("#websocket-message-type").val(), JSON.parse($("#websocket-message-content").val()));
+  dispatcher.send($("#websocket-message-content").val());
 };
 
 $("#send-to-websocket").click(sendStuff);
diff --git a/services/api/Gemfile b/services/api/Gemfile
index e50802e..8e4aa18 100644
--- a/services/api/Gemfile
+++ b/services/api/Gemfile
@@ -62,6 +62,7 @@ gem 'test_after_commit', :group => :test
 
 gem 'google-api-client', '~> 0.6.3'
 gem 'trollop'
+gem 'faye-websocket'
 
 gem 'themes_for_rails'
 
diff --git a/services/api/Gemfile.lock b/services/api/Gemfile.lock
index 7a516d5..c87acc6 100644
--- a/services/api/Gemfile.lock
+++ b/services/api/Gemfile.lock
@@ -70,10 +70,14 @@ GEM
     curb (0.8.5)
     daemon_controller (1.2.0)
     erubis (2.7.0)
+    eventmachine (1.0.3)
     execjs (2.0.2)
     extlib (0.9.16)
     faraday (0.8.9)
       multipart-post (~> 1.2.0)
+    faye-websocket (0.7.2)
+      eventmachine (>= 0.12.0)
+      websocket-driver (>= 0.3.1)
     google-api-client (0.6.4)
       addressable (>= 2.3.2)
       autoparse (>= 0.3.3)
@@ -193,6 +197,7 @@ GEM
       execjs (>= 0.3.0)
       json (>= 1.8.0)
     uuidtools (2.1.4)
+    websocket-driver (0.3.2)
 
 PLATFORMS
   ruby
@@ -202,6 +207,7 @@ DEPENDENCIES
   andand
   arvados-cli (>= 0.1.20140328152103)
   coffee-rails (~> 3.2.0)
+  faye-websocket
   google-api-client (~> 0.6.3)
   jquery-rails
   multi_json
diff --git a/services/api/app/middlewares/rack_socket.rb b/services/api/app/middlewares/rack_socket.rb
new file mode 100644
index 0000000..7fcba83
--- /dev/null
+++ b/services/api/app/middlewares/rack_socket.rb
@@ -0,0 +1,38 @@
+
+  require 'faye/websocket'
+
+  class RackSocket
+
+    DEFAULT_ENDPOINT  = '/websocket'
+
+    def initialize(app = nil, options = nil)
+      @app = app if app.respond_to?(:call)
+      @options = [app, options].grep(Hash).first || {}
+      @endpoint = @options[:mount] || DEFAULT_ENDPOINT
+    end
+
+    def call env
+      request = Rack::Request.new(env)
+      if request.path_info == @endpoint and Faye::WebSocket.websocket?(env)
+        ws = Faye::WebSocket.new(env)
+
+        ws.on :message do |event|
+          puts "got #{event.data}"
+          ws.send(event.data)
+        end
+
+        ws.on :close do |event|
+          p [:close, event.code, event.reason]
+          ws = nil
+        end
+
+        # Return async Rack response
+        ws.rack_response
+      else
+        @app.call env
+      end
+    end
+
+  end
+
+
diff --git a/services/api/config/initializers/eventbus.rb b/services/api/config/initializers/eventbus.rb
new file mode 100644
index 0000000..2350b57
--- /dev/null
+++ b/services/api/config/initializers/eventbus.rb
@@ -0,0 +1,3 @@
+Server::Application.configure do
+  config.middleware.insert_before ActionDispatch::Static, RackSocket
+end

commit 4e047434f0c6958db039cf9ab55e3f7f44da44c9
Author: Peter Amstutz <tetron at arvados-dev>
Date:   Mon Apr 21 13:31:39 2014 -0400

    Websocket event testing page.

diff --git a/apps/workbench/app/controllers/websocket_controller.rb b/apps/workbench/app/controllers/websocket_controller.rb
new file mode 100644
index 0000000..a49c15f
--- /dev/null
+++ b/apps/workbench/app/controllers/websocket_controller.rb
@@ -0,0 +1,10 @@
+class WebsocketController < ApplicationController
+  skip_before_filter :find_objects_for_index
+
+  def index
+  end
+
+  def model_class
+    "Websocket"
+  end
+end
diff --git a/apps/workbench/app/views/websocket/index.html.erb b/apps/workbench/app/views/websocket/index.html.erb
new file mode 100644
index 0000000..d4259a9
--- /dev/null
+++ b/apps/workbench/app/views/websocket/index.html.erb
@@ -0,0 +1,32 @@
+<% content_for :page_title do %>
+  Event bus debugging page
+<% end %>
+<h1>Event bus debugging page</h1>
+
+<form>
+<input type="text" style="width:100%" id="websocket-message-type">
+<textarea style="width:100%; height: 10em" id="websocket-message-content"></textarea>
+<button type="button" id="send-to-websocket">Send</button>
+</form>
+
+<br>
+
+<p id="PutStuffHere"></p>
+
+<script>
+$(function() {
+putStuffThere = function (content) {
+  $("#PutStuffHere").append(content["message"] + "<br>");
+};
+
+var dispatcher = new WebSocketRails('localhost:3032/arvados/v1/events?api_token=<%= Thread.current[:arvados_api_token] %>');
+dispatcher.bind('hello', putStuffThere);
+
+sendStuff = function () {
+  dispatcher.trigger($("#websocket-message-type").val(), JSON.parse($("#websocket-message-content").val()));
+};
+
+$("#send-to-websocket").click(sendStuff);
+});
+
+</script>
diff --git a/apps/workbench/config/routes.rb b/apps/workbench/config/routes.rb
index 8c89238..9d7a3c9 100644
--- a/apps/workbench/config/routes.rb
+++ b/apps/workbench/config/routes.rb
@@ -43,6 +43,7 @@ ArvadosWorkbench::Application.routes.draw do
   get '/collections/:uuid/*file' => 'collections#show_file', :format => false
 
   post 'actions' => 'actions#post'
+  get 'websockets' => 'websocket#index'
 
   root :to => 'users#welcome'
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list