[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