websockets is just a hair faster and easier to implement. just sayin'.

This commit is contained in:
John Bintz 2012-03-21 18:41:29 -04:00
parent ed00ba476a
commit 9de5460533
7 changed files with 70 additions and 102 deletions

View File

@ -33,5 +33,6 @@ Gem::Specification.new do |gem|
gem.add_dependency 'sprockets'
gem.add_dependency 'sprockets-vendor_gems'
gem.add_dependency 'thin'
gem.add_dependency 'em-websocket'
end

View File

@ -3,77 +3,18 @@
#= require flowerbox/exception
#
Flowerbox =
baseUrl: '/'
debug: false
ping: ->
Flowerbox.contact('ping')
contactQueue: []
contact: (url, data...) ->
Flowerbox.started = true
if !Flowerbox.debug
Flowerbox.contactQueue.push([url, data])
Flowerbox.socket.send(JSON.stringify([ url, data ]))
Flowerbox.done = true if url == 'results'
queueIndex: 0
delay: 40
started: false
done: false
xhrObjects: {}
onQueueStateChange: ->
queueRunner: (failsafe = 5) ->
Flowerbox.onQueueStateChange("checking queue")
if Flowerbox.contactQueue.length > 0
Flowerbox.started = true
info = Flowerbox.contactQueue.shift()
[ url, data ] = info
xhr = new XMLHttpRequest()
xhr.open("POST", Flowerbox.baseUrl + url, true)
xhr.setRequestHeader("Accept", "application/json")
done = false
xhr.onreadystatechange = ->
if xhr.readyState == 4
done = true
Flowerbox.onQueueStateChange("done #{url}")
if url == "results"
Flowerbox.onQueueStateChange("finsihed all tests")
Flowerbox.done = true
else
setTimeout(
->
Flowerbox.queueRunner()
, 1
)
Flowerbox.onQueueStateChange("running #{url}")
setTimeout(
->
if xhr.readyState != 4
xhr.abort()
Flowerbox.onQueueStateChange("aborted #{url}, rerunning")
Flowerbox.contactQueue.unshift(info)
if failsafe > 0
failsafe -= 1
Flowerbox.queueRunner(failsafe)
, Flowerbox.delay * 5
)
xhr.send(JSON.stringify(data))
else
Flowerbox.startQueueRunner()
startQueueRunner: ->
setTimeout(
->
Flowerbox.queueRunner()
, Flowerbox.delay
)
fail: ->

View File

@ -48,19 +48,15 @@ module Flowerbox
end
command :ping do
runner.ping
end
command :pause_timer do
runner.pause_timer
end
command :unpause_timer do
runner.unpause_timer
end
command :starting do
runner.did_start!
end
get %r{^/__F__/(.*)$} do |file|

View File

@ -140,7 +140,7 @@ module Flowerbox
server_options[:logging] = true if options[:verbose_server]
server_options[:port] = Flowerbox.port
Flowerbox.server = Flowerbox::Server.new(server_options)
Flowerbox.server = Flowerbox::Server.new(self, server_options)
end
def log(message)

View File

@ -22,13 +22,13 @@ module Flowerbox
def configured?
File.directory?(File.join(Dir.pwd, 'node_modules/jsdom')) &&
File.directory?(File.join(Dir.pwd, 'node_modules/xmlhttprequest'))
File.directory?(File.join(Dir.pwd, 'node_modules/ws'))
end
def cleanup ; end
def configure
system %{bash -c "mkdir -p node_modules && npm link jsdom && npm link xmlhttprequest"}
system %{bash -c "mkdir -p node_modules && npm link jsdom && npm link ws"}
end
def run(sprockets, spec_files, options)
@ -53,7 +53,7 @@ var fs = require('fs'),
vm = require('vm'),
http = require('http'),
jsdom = require('jsdom'),
xhr = require('xmlhttprequest')
ws = require('ws')
// expand the sandbox a bit
var context = function() {};
@ -62,7 +62,7 @@ for (method in global) { context[method] = global[method]; }
jsdom.env(
"<html><head><title></title></head><body></body></html>", [], function(errors, window) {
context.window = window;
context.XMLHttpRequest = xhr.XMLHttpRequest;
context.WebSocket = ws;
var gotFlowerbox = false;
@ -106,23 +106,20 @@ jsdom.env(
request.end();
} else {
#{env}
context.Flowerbox.socket = new ws('ws://localhost:#{server.port + 1}/');
context.Flowerbox.socket.onopen = function() {
#{env}
context.Flowerbox.onQueueStateChange = function(msg) {
//console.log(msg);
var waitForFinish;
waitForFinish = function() {
if (!context.Flowerbox.started || !context.Flowerbox.done) {
process.nextTick(waitForFinish);
} else {
process.exit(0);
}
};
waitForFinish();
};
context.Flowerbox.startQueueRunner()
var waitForFinish;
waitForFinish = function() {
if (!context.Flowerbox.started || !context.Flowerbox.done) {
process.nextTick(waitForFinish);
} else {
process.exit(0);
}
};
waitForFinish();
}
};
fileRunner();

View File

@ -70,8 +70,10 @@ console.log = function(msg) {
var context = this;
window.addEventListener('DOMContentLoaded', function() {
#{env}
Flowerbox.startQueueRunner()
Flowerbox.socket = new WebSocket('ws://localhost:#{server.port + 1}/');
Flowerbox.socket.onopen = function() {
#{env}
};
}, false);
</script>
</body>

View File

@ -3,16 +3,19 @@ require 'net/http'
require 'socket'
require 'rack/builder'
require 'thin'
require 'eventmachine'
require 'em-websocket'
module Flowerbox
class Server
attr_reader :options
attr_reader :runner
class MissingRackApp < StandardError ; end
class ServerDiedError < StandardError ; end
def initialize(options = {})
def initialize(runner, options = {})
@runner = runner
@options = { :logging => false }.merge(options || {})
end
@ -22,23 +25,51 @@ module Flowerbox
def start
@server_thread = Thread.new do
server_options = { :Port => port, :Host => interface }
EventMachine.run do
server_options = { :Port => port, :Host => interface }
Thin::Logging.silent = !options[:logging]
Thin::Logging.silent = !options[:logging]
rack_app = app
rack_app = app
if options[:logging]
rack_app = ::Rack::Builder.new do
use ::Rack::CommonLogger, STDOUT
run app
if options[:logging]
rack_app = ::Rack::Builder.new do
use ::Rack::CommonLogger, STDOUT
run app
end
end
end
::Rack::Handler::Thin.run(rack_app, server_options) do |server|
Thread.current[:server] = server
EventMachine::WebSocket.start(:host => interface, :port => port + 1) do |ws|
ws.onmessage { |message|
command, data = JSON.parse(message)
trap('QUIT') { server.stop }
case command
when 'starting'
runner.did_start!
when 'unpause_timer'
runner.unpause_timer
when 'pause_timer'
runner.pause_timer
when 'ping'
runner.ping
when 'log'
runner.log(data.first)
when 'finish_test'
runner.add_results(data.flatten)
when 'start_test'
runner.add_tests(data.flatten)
when 'results'
runner.finish!(data.flatten.first)
end
}
end
::Rack::Handler::Thin.run(rack_app, server_options) do |server|
Thread.current[:server] = server
trap('QUIT') { server.stop }
end
end
end
@ -69,7 +100,7 @@ module Flowerbox
begin
attempts -= 1
current_port = random_port
current_port = (random_port / 2).floor * 2
begin
socket = TCPSocket.new(interface, current_port)