scales-monitor 0.0.1.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/Rakefile +8 -0
- data/bin/scales-monitor +8 -0
- data/lib/scales-monitor.rb +11 -0
- data/lib/scales-monitor/app/Gemfile +3 -0
- data/lib/scales-monitor/app/Rakefile +0 -0
- data/lib/scales-monitor/app/app/assets/images/.gitignore +0 -0
- data/lib/scales-monitor/app/app/assets/images/glyphicons-halflings-white.png +0 -0
- data/lib/scales-monitor/app/app/assets/images/glyphicons-halflings.png +0 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/config/config.js.coffee +8 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/config/routes.js.coffee +15 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/controllers/.gitignore +0 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/controllers/log.jst.coffee +58 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/controllers/machines.js.coffee +60 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/controllers/queues.js.coffee +55 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/controllers/resources.js.coffee +128 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/index.js.coffee +8 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/models/.gitignore +0 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/models/socket.js.coffee +9 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/.gitignore +0 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/_format_bar.jst.eco +10 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/_machine.jst.eco +11 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/_queue_item.jst.eco +10 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/_resource.jst.eco +5 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/_top.jst.eco +1 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/log.jst.eco +11 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/machines.jst.eco +33 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/queues.jst.eco +33 -0
- data/lib/scales-monitor/app/app/assets/javascripts/app/views/resources.jst.eco +31 -0
- data/lib/scales-monitor/app/app/assets/javascripts/application.js.coffee +16 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/bootstrap.js +1825 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/jquery.js +4 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/jquery.timeago.js +152 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/json2.js +485 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/ajax.coffee +208 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/list.coffee +43 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/local.coffee +16 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/manager.coffee +83 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/relation.coffee +144 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/route.coffee +145 -0
- data/lib/scales-monitor/app/app/assets/javascripts/lib/spine/spine.coffee +537 -0
- data/lib/scales-monitor/app/app/assets/stylesheets/application.css.scss +58 -0
- data/lib/scales-monitor/app/app/assets/stylesheets/bootstrap-docs.css +845 -0
- data/lib/scales-monitor/app/app/assets/stylesheets/bootstrap-responsive.css +815 -0
- data/lib/scales-monitor/app/app/assets/stylesheets/bootstrap.css +4983 -0
- data/lib/scales-monitor/app/app/views/index.html.erb +45 -0
- data/lib/scales-monitor/app/config.ru +3 -0
- data/lib/scales-monitor/app/config/config.rb +17 -0
- data/lib/scales-monitor/app/config/routes.rb +13 -0
- data/lib/scales-monitor/app/public/assets/.gitignore +0 -0
- data/lib/scales-monitor/app/public/assets/application.css +6709 -0
- data/lib/scales-monitor/app/public/assets/application.js +5563 -0
- data/lib/scales-monitor/app/public/assets/glyphicons-halflings-white.png +0 -0
- data/lib/scales-monitor/app/public/assets/glyphicons-halflings.png +0 -0
- data/lib/scales-monitor/app/public/index.html +45 -0
- data/lib/scales-monitor/base.rb +17 -0
- data/lib/scales-monitor/boot/autoload.rb +5 -0
- data/lib/scales-monitor/boot/initializers/goliath.rb +3 -0
- data/lib/scales-monitor/monitor.rb +33 -0
- data/lib/scales-monitor/version.rb +5 -0
- data/lib/scales-monitor/web_socket.rb +180 -0
- data/scales-monitor.gemspec +24 -0
- data/spec/gem_spec.rb +7 -0
- data/spec/helper.rb +50 -0
- data/spec/monitor_spec.rb +50 -0
- data/spec/web_socket_spec.rb +103 -0
- metadata +174 -0
Binary file
|
Binary file
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Scales | Monitor</title>
|
5
|
+
<link href='assets/application.css' media='all' rel='stylesheet' type='text/css'>
|
6
|
+
<script src='assets/application.js' type='text/javascript'></script>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
|
10
|
+
<div class="navbar navbar-fixed-top">
|
11
|
+
<div class="navbar-inner">
|
12
|
+
<div class="container">
|
13
|
+
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
14
|
+
<span class="icon-bar"></span>
|
15
|
+
<span class="icon-bar"></span>
|
16
|
+
<span class="icon-bar"></span>
|
17
|
+
</button>
|
18
|
+
<a class="brand" href="/">Scales Monitor</a>
|
19
|
+
<div class="nav-collapse collapse">
|
20
|
+
<ul class="nav">
|
21
|
+
<li class="" id="nav_machines">
|
22
|
+
<a href="#/machines">Machines</a>
|
23
|
+
</li>
|
24
|
+
<li class="" id="nav_queues">
|
25
|
+
<a href="#/queues">Queues</a>
|
26
|
+
</li>
|
27
|
+
<li class="" id="nav_resources">
|
28
|
+
<a href="#/resources">Resources</a>
|
29
|
+
</li>
|
30
|
+
<li class="" id="nav_log">
|
31
|
+
<a href="#/log">Log</a>
|
32
|
+
</li>
|
33
|
+
</ul>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
<div class="container">
|
40
|
+
<div id="app"></div>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
|
44
|
+
</body>
|
45
|
+
</html>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Scales
|
2
|
+
module Monitor
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def run!
|
6
|
+
ARGV << "--stdout" << "--environment" << "#{Scales.env}"
|
7
|
+
|
8
|
+
monitor = WebSocket.new
|
9
|
+
runner = Goliath::Runner.new(ARGV, monitor)
|
10
|
+
runner.app = Goliath::Rack::Builder.build(WebSocket, monitor)
|
11
|
+
runner.load_plugins(WebSocket.plugins)
|
12
|
+
runner.run
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Scales
|
2
|
+
module Monitor
|
3
|
+
|
4
|
+
PUBLIC_APP_DIR = File.expand_path("../app/public", __FILE__)
|
5
|
+
|
6
|
+
module Monitor
|
7
|
+
|
8
|
+
@@cache = nil
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def serve(path)
|
13
|
+
cache_files! if @@cache.nil?
|
14
|
+
@@cache[path]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def cache_files!
|
20
|
+
@@cache = {}
|
21
|
+
|
22
|
+
Dir.chdir(PUBLIC_APP_DIR)
|
23
|
+
Dir["*.html", "assets/*"].each{ |file| @@cache["/#{file}"] = File.read(file) }
|
24
|
+
Dir.chdir(Scales.pwd)
|
25
|
+
|
26
|
+
@@cache["/"] = @@cache["/index.html"]
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Scales
|
2
|
+
module Monitor
|
3
|
+
|
4
|
+
class WebSocket < Goliath::WebSocket
|
5
|
+
use Server::ContentType, 'html'
|
6
|
+
|
7
|
+
def on_open(env)
|
8
|
+
send_initial_statuses(env)
|
9
|
+
setup_subscription
|
10
|
+
add_to_subscribers(env)
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_error(env, error)
|
14
|
+
env.logger.error error
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_message(env, msg)
|
18
|
+
env.stream_send(msg)
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_close(env)
|
22
|
+
remove_from_subscribers(env) if env['REQUEST_PATH'] == "/socket"
|
23
|
+
end
|
24
|
+
|
25
|
+
def response(env)
|
26
|
+
path = env['REQUEST_PATH']
|
27
|
+
|
28
|
+
if path == '/socket'
|
29
|
+
super(env)
|
30
|
+
else
|
31
|
+
[200, {}, Monitor.serve(path)]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def setup_subscription
|
38
|
+
return if @subscribed
|
39
|
+
@subscribers = []
|
40
|
+
|
41
|
+
events = Storage::Async.new_connection!
|
42
|
+
events.subscribe("scales_monitor_events")
|
43
|
+
events.on(:message) do |channel, message|
|
44
|
+
@subscribers.each { |subscriber| subscriber.stream_send(message) }
|
45
|
+
end
|
46
|
+
@subscribed = true
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_to_subscribers(env)
|
50
|
+
@subscribers << env
|
51
|
+
end
|
52
|
+
|
53
|
+
def remove_from_subscribers(env)
|
54
|
+
@subscribers.delete(env)
|
55
|
+
end
|
56
|
+
|
57
|
+
def send_initial_statuses(env)
|
58
|
+
server_statuses.each{ |server| env.stream_send(server) }
|
59
|
+
cache_statuses.each{ |cache| env.stream_send(cache) }
|
60
|
+
worker_statuses.each{ |worker| env.stream_send(worker) }
|
61
|
+
|
62
|
+
request_queue.each{ |request| env.stream_send(request) }
|
63
|
+
response_queue.each{ |request| env.stream_send(response) }
|
64
|
+
|
65
|
+
push_resources.each{ |resource| env.stream_send(resource) }
|
66
|
+
push_partials.each{ |partial| env.stream_send(partial) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def server_statuses
|
70
|
+
servers = Storage::Async.connection.keys("scales_server_*")
|
71
|
+
return [] if servers.empty?
|
72
|
+
|
73
|
+
Storage::Async.connection.mget(*servers)
|
74
|
+
end
|
75
|
+
|
76
|
+
def cache_statuses
|
77
|
+
info = Storage::Async.connection.info
|
78
|
+
data = {
|
79
|
+
:id => redis_value("run_id", info)[0..16],
|
80
|
+
:key => "",
|
81
|
+
:type => "cache_started",
|
82
|
+
:spawned_at => Time.now.to_i - redis_value("uptime_in_seconds", info).to_i,
|
83
|
+
:env => Scales.env,
|
84
|
+
:ip => Scales.config.host,
|
85
|
+
:port => Scales.config.port
|
86
|
+
}
|
87
|
+
[JSON.generate(data)]
|
88
|
+
end
|
89
|
+
|
90
|
+
def worker_statuses
|
91
|
+
workers = Storage::Async.connection.keys("scales_worker_*")
|
92
|
+
return [] if workers.empty?
|
93
|
+
|
94
|
+
Storage::Async.connection.mget(*workers)
|
95
|
+
end
|
96
|
+
|
97
|
+
def request_queue
|
98
|
+
requests = Storage::Async.connection.llen("scales_request_queue")
|
99
|
+
return [] if requests == 0
|
100
|
+
|
101
|
+
data = []
|
102
|
+
Storage::Async.connection.lrange("scales_request_queue", 0, requests).each do |request|
|
103
|
+
job = JSON.parse(request)
|
104
|
+
data << {
|
105
|
+
:id => job['scales.id'],
|
106
|
+
:server_id => nil,
|
107
|
+
:type => "server_put_request_in_queue",
|
108
|
+
:path => job['PATH_INFO'],
|
109
|
+
:method => job['REQUEST_METHOD']
|
110
|
+
}.to_json
|
111
|
+
end
|
112
|
+
data
|
113
|
+
end
|
114
|
+
|
115
|
+
def response_queue
|
116
|
+
responses = Storage::Async.connection.keys("scales_response_*")
|
117
|
+
return [] if responses.empty?
|
118
|
+
|
119
|
+
data = []
|
120
|
+
responses.each do |response_key|
|
121
|
+
response = Storage::Async.connection.lindex(response_key, 0)
|
122
|
+
response = JSON.parse(response)
|
123
|
+
data << {
|
124
|
+
:id => response[1]['scales.id'],
|
125
|
+
:worker_id => nil,
|
126
|
+
:type => "worker_put_response_in_queue",
|
127
|
+
:path => response[1]['PATH_INFO'],
|
128
|
+
:method => response[1]['REQUEST_METHOD'],
|
129
|
+
:status => response[0]
|
130
|
+
}.to_json
|
131
|
+
end
|
132
|
+
data
|
133
|
+
end
|
134
|
+
|
135
|
+
def push_resources
|
136
|
+
resources = Storage::Async.connection.keys("scales_resource_/*")
|
137
|
+
return [] if resources.empty?
|
138
|
+
|
139
|
+
data = []
|
140
|
+
resources.each do |resource|
|
141
|
+
data << {
|
142
|
+
:path => resource.gsub("scales_resource_", ""),
|
143
|
+
:format => format(resource),
|
144
|
+
:type => "push_resource"
|
145
|
+
}.to_json
|
146
|
+
end
|
147
|
+
data
|
148
|
+
end
|
149
|
+
|
150
|
+
def push_partials
|
151
|
+
partials = Storage::Async.connection.keys("scales_partial_*")
|
152
|
+
return [] if partials.empty?
|
153
|
+
|
154
|
+
data = []
|
155
|
+
partials.each do |partial|
|
156
|
+
data << {
|
157
|
+
:path => partial.gsub("scales_partial_", ""),
|
158
|
+
:format => format(partial),
|
159
|
+
:type => "push_partial"
|
160
|
+
}.to_json
|
161
|
+
end
|
162
|
+
data
|
163
|
+
end
|
164
|
+
|
165
|
+
private
|
166
|
+
|
167
|
+
def redis_value(value, info)
|
168
|
+
info.scan(/^#{value}:.*/).first.split(":").last
|
169
|
+
end
|
170
|
+
|
171
|
+
def format(path)
|
172
|
+
format = "HTML"
|
173
|
+
Scales::Helper::ContentTypes::TYPES.each { |aformat, type| format = aformat.to_s.upcase and break if path =~ /\.#{aformat}(\?|$)/ }
|
174
|
+
format
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/scales-monitor/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Thomas Fankhauser"]
|
6
|
+
gem.email = ["tommylefunk@googlemail.com"]
|
7
|
+
gem.description = %q{Super Scale Caching Framework - Monitor Server}
|
8
|
+
gem.summary = %q{Monitoring in the form of a website that updates in real-time using a websocket connected to the main system.}
|
9
|
+
gem.homepage = "http://itscales.org"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "scales-monitor"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Scales::Monitor::VERSION
|
17
|
+
|
18
|
+
# Dependencies
|
19
|
+
gem.add_dependency "rake", ">= 0.9.2.2"
|
20
|
+
gem.add_dependency "rspec", ">= 2.11"
|
21
|
+
gem.add_dependency "scales-core", Scales::Monitor::VERSION
|
22
|
+
gem.add_dependency "scales-server", Scales::Monitor::VERSION
|
23
|
+
gem.add_dependency "goliath", ">= 1.0.0.beta.1"
|
24
|
+
end
|
data/spec/gem_spec.rb
ADDED
data/spec/helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'scales-monitor'
|
2
|
+
require "net/http"
|
3
|
+
require "uri"
|
4
|
+
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
def async
|
8
|
+
if EM.reactor_running?
|
9
|
+
yield
|
10
|
+
else
|
11
|
+
out = nil
|
12
|
+
EM.synchrony do
|
13
|
+
out = yield
|
14
|
+
EM.stop
|
15
|
+
end
|
16
|
+
out
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def get url
|
21
|
+
uri = URI.parse(url)
|
22
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
23
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
24
|
+
|
25
|
+
http.request(request)
|
26
|
+
end
|
27
|
+
|
28
|
+
def post url, data = {}
|
29
|
+
uri = URI.parse(url)
|
30
|
+
Net::HTTP.post_form(uri, data)
|
31
|
+
end
|
32
|
+
|
33
|
+
def fixture(file)
|
34
|
+
File.read(File.expand_path("../fixtures/#{file}", __FILE__))
|
35
|
+
end
|
36
|
+
|
37
|
+
def squeeze string
|
38
|
+
string.gsub(/(\n|\t|\r)/, ' ').gsub(/>\s*</, '><').squeeze(' ').strip
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
RSpec.configure do |config|
|
44
|
+
config.include Helpers
|
45
|
+
config.include Goliath::TestHelper
|
46
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
47
|
+
config.before(:suite) do
|
48
|
+
Scales::Storage::Sync.flushall!
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Scales::Monitor::Monitor do
|
4
|
+
|
5
|
+
it "serves paths from cache" do
|
6
|
+
described_class.serve("/").should have_at_least(100).characters
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Scales::Monitor do
|
12
|
+
|
13
|
+
before :all do
|
14
|
+
@server_pid = fork do
|
15
|
+
trap('INT') do
|
16
|
+
exit 0
|
17
|
+
end
|
18
|
+
|
19
|
+
Scales::Storage::Sync.force_reconnect!
|
20
|
+
|
21
|
+
ARGV << "-p" << "9000"
|
22
|
+
Scales::Monitor.run!
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Waiting for monitor server to spawn ..."
|
26
|
+
sleep 2
|
27
|
+
end
|
28
|
+
|
29
|
+
after :all do
|
30
|
+
Process.kill("INT", @server_pid)
|
31
|
+
Process.wait
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should answer requests" do
|
35
|
+
EventMachine.run {
|
36
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:9000/').aget
|
37
|
+
|
38
|
+
http.errback {
|
39
|
+
EventMachine.stop
|
40
|
+
fail "Request did not work!"
|
41
|
+
}
|
42
|
+
http.callback {
|
43
|
+
http.response_header.status.should == 200
|
44
|
+
http.response.should have_at_least(100).characters
|
45
|
+
EventMachine.stop
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Scales::Monitor::WebSocket do
|
4
|
+
|
5
|
+
context "static files" do
|
6
|
+
|
7
|
+
it "serves cached html files" do
|
8
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
9
|
+
get_request(:path => "/") do |client|
|
10
|
+
client.response_header['CONTENT_TYPE'].should =~ %r{^text/html}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "serves cached json files" do
|
16
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
17
|
+
get_request(:path => "/assets/application.js") do |client|
|
18
|
+
client.response_header['CONTENT_TYPE'].should =~ %r{^application/javascript}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context "initial statuses" do
|
26
|
+
|
27
|
+
it "sends servers" do
|
28
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
29
|
+
Scales::Storage::Async.connection.set("scales_server_725634", "server1")
|
30
|
+
Scales::Storage::Async.connection.set("scales_server_8768fk", "server2")
|
31
|
+
|
32
|
+
servers = described_class.new.instance_eval{ server_statuses }
|
33
|
+
servers.include?("server1").should be_true
|
34
|
+
servers.include?("server2").should be_true
|
35
|
+
EM.stop
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "sends workers" do
|
40
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
41
|
+
Scales::Storage::Async.connection.set("scales_worker_725634", "worker1")
|
42
|
+
Scales::Storage::Async.connection.set("scales_worker_8768fk", "worker2")
|
43
|
+
|
44
|
+
workers = described_class.new.instance_eval{ worker_statuses }
|
45
|
+
workers.include?("worker1").should be_true
|
46
|
+
workers.include?("worker2").should be_true
|
47
|
+
EM.stop
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "sends requests" do
|
52
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
53
|
+
json = "{\"scales.id\":\"4f57fcec795b6a6158796a1958e781f0\",\"SERVER_NAME\":\"0.0.0.0\",\"SERVER_PORT\":\"3005\",\"REQUEST_METHOD\":\"POST\",\"QUERY_STRING\":\"\",\"PATH_INFO\":\"/tracks\",\"HTTP_HOST\":\"0.0.0.0:3005\",\"HTTP_USER_AGENT\":\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.19 (KHTML, like Gecko) Version/6.0 Safari/536.19\",\"HTTP_ACCEPT\":\"text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8\",\"HTTP_ORIGIN\":\"http://0.0.0.0:3005\",\"HTTP_REFERER\":\"http://0.0.0.0:3005/tracks/new\",\"HTTP_ACCEPT_LANGUAGE\":\"en-us\",\"HTTP_ACCEPT_ENCODING\":\"gzip, deflate\",\"HTTP_CONNECTION\":\"keep-alive\",\"HTTP_VERSION\":\"1.1\",\"rack.version\":[1,0],\"rack.url_scheme\":null,\"rack.input\":\"utf8=%E2%9C%93&authenticity_token=gniWYAZpl67rSI0VYfrpoBXJ3Ipv9ZEv9VY9FSbyoDM%3D&track%5Bname%5D=Next+one&track%5Bartist%5D=Okay+here&commit=Create+Track\"}"
|
54
|
+
Scales::Storage::Async.connection.lpush("scales_request_queue", json)
|
55
|
+
Scales::Storage::Async.connection.lpush("scales_request_queue", json)
|
56
|
+
|
57
|
+
requests = described_class.new.instance_eval{ request_queue }
|
58
|
+
requests.should have_at_least(2).requests
|
59
|
+
EM.stop
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "sends responds" do
|
64
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
65
|
+
json = "[302,{\"Location\":\"http://0.0.0.0:3005/tracks/170\",\"Content-Type\":\"text/html; charset=utf-8\",\"Set-Cookie\":\"_app_session=BAh7B0kiCmZsYXNoBjoGRUZvOiVBY3Rpb25EaXNwYXRjaDo6Rmxhc2g6OkZsYXNoSGFzaAk6CkB1c2VkbzoIU2V0BjoKQGhhc2h7ADoMQGNsb3NlZEY6DUBmbGFzaGVzewY6C25vdGljZUkiJFRyYWNrIHdhcyBzdWNjZXNzZnVsbHkgY3JlYXRlZC4GOwBGOglAbm93MEkiD3Nlc3Npb25faWQGOwBGSSIlZDkxNDA4OTFmMWVhZTJlNGU2MmM3MmRkOTA4NDZjODUGOwBU--fd4912d39bd51eedcd5bf0519a939e5b38317b34; path=/; HttpOnly\",\"scales.id\":\"155a255dd3604fa2e39469e30aef3206\"},\"<html><body>You are being <a href=\\\"http://0.0.0.0:3005/tracks/170\\\">redirected</a>.</body></html>\"]"
|
66
|
+
Scales::Storage::Async.connection.lpush("scales_response_155a255dd3604fa2e39469e30aef3206", json)
|
67
|
+
Scales::Storage::Async.connection.lpush("scales_response_155a255dd3604fa2e39469e30aef3207", json)
|
68
|
+
|
69
|
+
responses = described_class.new.instance_eval{ response_queue }
|
70
|
+
responses.should have_at_least(2).responses
|
71
|
+
EM.stop
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "sends push resources" do
|
76
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
77
|
+
Scales::Storage::Async.flushall!
|
78
|
+
Scales::Storage::Async.set_content "/tracks", "test 1"
|
79
|
+
Scales::Storage::Async.set_content "/tracks/2", "test 2"
|
80
|
+
|
81
|
+
resources = described_class.new.instance_eval{ push_resources }
|
82
|
+
resources.should have_at_least(2).resources
|
83
|
+
EM.stop
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "sends push partials" do
|
88
|
+
with_api(described_class, {:verbose => true, :log_stdout => true}) do |server|
|
89
|
+
Scales::Storage::Async.flushall!
|
90
|
+
Scales::Storage::Async.set_content "tracks", "test 1"
|
91
|
+
Scales::Storage::Async.set_content "tracks/2", "test 2"
|
92
|
+
|
93
|
+
partials = described_class.new.instance_eval{ push_partials }
|
94
|
+
partials.should have_at_least(2).partials
|
95
|
+
EM.stop
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
end
|