From 154f32219a7eb6c50b41bba6923a901313ca7c45 Mon Sep 17 00:00:00 2001 From: Paul Asmuth Date: Tue, 5 Jun 2012 11:24:46 +0200 Subject: [PATCH] switched to rack/websocket - finally :) --- fnordmetric.gemspec | 6 ++--- lib/fnordmetric.rb | 3 +++ lib/fnordmetric/ext.rb | 11 ++++++++ lib/fnordmetric/web/reactor.rb | 14 +++++++--- lib/fnordmetric/web/web.rb | 19 ++++++++----- lib/fnordmetric/web/websocket.rb | 46 +++++++++++++------------------- web/js/fnordmetric.js | 4 +-- 7 files changed, 58 insertions(+), 45 deletions(-) diff --git a/fnordmetric.gemspec b/fnordmetric.gemspec index cdf81fc8b..a644acccc 100644 --- a/fnordmetric.gemspec +++ b/fnordmetric.gemspec @@ -18,15 +18,15 @@ Gem::Specification.new do |s| s.add_dependency "sinatra", ">= 1.2.6" s.add_dependency "redis", ">= 2.2.2" s.add_dependency "eventmachine" - s.add_dependency "em-websocket" - s.add_dependency "em-hiredis" + s.add_dependency "websocket-rack", "0.4.0" + s.add_dependency "em-hiredis", "0.1.1" s.add_dependency "json" s.add_dependency "i18n" s.add_dependency "haml" s.add_dependency "rack" s.add_dependency "rack-test" s.add_dependency "yajl-ruby" - s.add_dependency "thin" + s.add_dependency "thin", "~> 1.3.0" s.add_dependency "activesupport" s.add_development_dependency "delorean" diff --git a/lib/fnordmetric.rb b/lib/fnordmetric.rb index d147b2cc6..d58e7fbd9 100644 --- a/lib/fnordmetric.rb +++ b/lib/fnordmetric.rb @@ -5,7 +5,10 @@ require 'yajl' require 'sinatra/base' require 'haml' +require 'json' +require "thin" require 'rack/server' +require 'rack/websocket' require "fnordmetric/ext" require "fnordmetric/version" diff --git a/lib/fnordmetric/ext.rb b/lib/fnordmetric/ext.rb index f5623625e..4a9584562 100644 --- a/lib/fnordmetric/ext.rb +++ b/lib/fnordmetric/ext.rb @@ -61,4 +61,15 @@ def emtpy self.size == 0 end +end + +class Thin::Connection + + alias :pre_process_orig :pre_process + + def pre_process + @request.env['async.connection'] = self + pre_process_orig + end + end \ No newline at end of file diff --git a/lib/fnordmetric/web/reactor.rb b/lib/fnordmetric/web/reactor.rb index d7afe5743..9ec0eab0b 100644 --- a/lib/fnordmetric/web/reactor.rb +++ b/lib/fnordmetric/web/reactor.rb @@ -4,17 +4,23 @@ def initialize @namespaces = FnordMetric.namespaces end - def execute(socket, event, messages = []) + def execute(*args) + execute_unsafe(*args) + rescue Exception => e + FnordMetric.error("reactor crashed: " + e.to_s); [] + end + +private + + def execute_unsafe(socket, event, messages = []) return false unless event["namespace"] return false unless ns = @namespaces[event["namespace"].to_sym] messages << discover(ns) if event["type"] == "discover_request" messages << widget(ns, event) if event["type"] == "widget_request" messages << gauge(ns, event) if event["type"] == "render_request" - messages.flatten.each{ |m| socket.send(m.to_json) if m } + messages.flatten.compact end -private - def widget(namespace, event) "FnordMetric::#{event["klass"]}".constantize.execute(namespace, event) # FIXPAUL end diff --git a/lib/fnordmetric/web/web.rb b/lib/fnordmetric/web/web.rb index 3a62240f9..d78ca7f0f 100644 --- a/lib/fnordmetric/web/web.rb +++ b/lib/fnordmetric/web/web.rb @@ -12,7 +12,17 @@ def initialize(opts) def initialized server = @opts[:server].downcase - app = FnordMetric::App.new(@opts) + + websocket = FnordMetric::WebSocket.new + webapp = FnordMetric::App.new(@opts) + + dispatch = Rack::Builder.app do + use Rack::CommonLogger + use Rack::ShowExceptions + + map("/stream"){ run websocket } + map("/"){ run webapp } + end unless ["thin", "hatetepe"].include? server raise "Need an EventMachine webserver, but #{server} isn't" @@ -22,16 +32,11 @@ def initialized port = @opts[:port] Rack::Server.start( - :app => app, + :app => dispatch, :server => server, :Host => host, :Port => port ) && FnordMetric.log("listening on http://#{host}:#{port}") - - FnordMetric::WebSocket.new( - :host => host, - :port => (port.to_i+1) - ) && FnordMetric.log("listening on ws://#{host}:#{port.to_i+1}") end end \ No newline at end of file diff --git a/lib/fnordmetric/web/websocket.rb b/lib/fnordmetric/web/websocket.rb index 7cf8c6ecc..8daa4a69c 100644 --- a/lib/fnordmetric/web/websocket.rb +++ b/lib/fnordmetric/web/websocket.rb @@ -1,42 +1,32 @@ require "eventmachine" -require "em-websocket" +require 'rack/websocket' require "em-hiredis" require "json" -class FnordMetric::WebSocket +class FnordMetric::WebSocket < Rack::WebSocket::Application - def initialize(opts) - @opts = { - :host => "0.0.0.0", - :port => 8080 - }.merge(opts) + def initialize + super @reactor = FnordMetric::Reactor.new - @uuid = "websocket-#{get_uuid}" - - start_websocket end -private - - def start_websocket - EventMachine::WebSocket.start(@opts) do |socket| - socket.onopen do - - socket.onmessage do |message| - #puts "received: #{message}" - begin - message = JSON.parse(message) - rescue - puts "websocket: invalid json" - else - message["_eid"] ||= get_uuid - message["_sender"] = @uuid - msg = @reactor.execute(socket, message) # FIXPAUL - end - end + def on_open(env) + # socket openened :) + end + def on_message(env, message) + begin + message = JSON.parse(message) + rescue + puts "websocket: invalid json" + else + message["_eid"] ||= get_uuid + message["_sender"] = @uuid + + @reactor.execute(self, message).each do |m| + send_data m.to_json end end end diff --git a/web/js/fnordmetric.js b/web/js/fnordmetric.js index aef7b793a..3e9b44520 100644 --- a/web/js/fnordmetric.js +++ b/web/js/fnordmetric.js @@ -155,9 +155,7 @@ var FnordMetric = (function(){ }; function connect(){ - var socket_url = document.location.hostname + ":" + (parseInt(document.location.port)+1); - - socket = new WebSocket("ws://" + socket_url); + socket = new WebSocket("ws://" + document.location.host + '/stream'); socket.onmessage = socketMessage; socket.onclose = socketClose; socket.onopen = socketOpen;