droid 0.9.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/bin/bleedq +19 -0
- data/droid.gemspec +100 -0
- data/examples/async_reply.rb +25 -0
- data/examples/heroku_async_reply.rb +22 -0
- data/examples/sync.rb +32 -0
- data/examples/worker.rb +58 -0
- data/lib/droid.rb +88 -476
- data/lib/droid/em.rb +55 -0
- data/lib/droid/heroku.rb +102 -0
- data/lib/droid/heroku/local_stats.rb +145 -0
- data/{vendor/logger_client/lib → lib/droid/heroku}/logger_client.rb +9 -5
- data/lib/droid/heroku/memcache_cluster.rb +129 -0
- data/lib/droid/heroku/stats.rb +30 -0
- data/lib/droid/json_server.rb +109 -0
- data/lib/droid/monkey.rb +8 -0
- data/lib/droid/publish.rb +24 -0
- data/lib/droid/queue.rb +196 -0
- data/lib/droid/request.rb +110 -0
- data/lib/droid/sync.rb +88 -0
- data/lib/droid/utilization.rb +113 -0
- data/lib/droid/utils.rb +113 -0
- data/lib/heroku_droid.rb +1 -86
- data/lib/local_stats.rb +1 -143
- data/lib/memcache_cluster.rb +1 -129
- data/lib/stats.rb +1 -30
- data/spec/publish_spec.rb +27 -0
- data/spec/response_spec.rb +47 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/utils_spec.rb +43 -0
- data/{test/wait_for_port_test.rb → spec/wait_for_port_spec.rb} +2 -9
- metadata +109 -35
- data/README.md +0 -34
- data/lib/utilization.rb +0 -90
- data/test/base.rb +0 -43
- data/test/droid_test.rb +0 -53
- data/test/heroku_droid_test.rb +0 -42
- data/vendor/logger_client/Rakefile +0 -53
- data/vendor/logger_client/init.rb +0 -1
- data/vendor/logger_client/test.rb +0 -18
data/README.md
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
Droid - our AMQP wrapper
|
2
|
-
========================
|
3
|
-
|
4
|
-
Every instance type in the heroku cloud runs an agent, which we call a droid. These report instance stats into opsdash, and give the instance a connection to our general AMQP backbone.
|
5
|
-
|
6
|
-
Setup
|
7
|
-
-----
|
8
|
-
|
9
|
-
To use droid from an app or component, add the following to that app's Gemfile:
|
10
|
-
|
11
|
-
gem 'droid', VERSION
|
12
|
-
|
13
|
-
Set VERSION to the [current version](http://rubygems.org/gems/droid).
|
14
|
-
|
15
|
-
Legacy setup
|
16
|
-
------------
|
17
|
-
|
18
|
-
Our pre-gem was to check out droid into /usr/local/droid on all instance types.
|
19
|
-
This is deprecated.
|
20
|
-
|
21
|
-
Releasing a new droid gem
|
22
|
-
-------------------------
|
23
|
-
|
24
|
-
$ gem install jeweler
|
25
|
-
$ echo "vX.X.X" > VERSION
|
26
|
-
$ rake build
|
27
|
-
$ git commit -am "vX.X.X"
|
28
|
-
$ git tag vX.X.X
|
29
|
-
$ git push origin master --tags
|
30
|
-
$ gem push pkg/droid-X.X.X.gem
|
31
|
-
|
32
|
-
Then increment the version number in the Gemfile for any component that you
|
33
|
-
wish to use the new version.
|
34
|
-
|
data/lib/utilization.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
module Utilization
|
2
|
-
extend self
|
3
|
-
|
4
|
-
@latency = 0.0
|
5
|
-
def latency=(val); @latency = val; end
|
6
|
-
def latency; @latency; end
|
7
|
-
|
8
|
-
@@start = Time.now
|
9
|
-
@@data = { }
|
10
|
-
|
11
|
-
def reinit
|
12
|
-
@@start = Time.now
|
13
|
-
@@data = { }
|
14
|
-
end
|
15
|
-
|
16
|
-
def data(topic)
|
17
|
-
@@data[topic] ||= {
|
18
|
-
'msgs' => 0,
|
19
|
-
'time' => 0.0
|
20
|
-
}
|
21
|
-
@@data[topic]
|
22
|
-
end
|
23
|
-
|
24
|
-
def topics
|
25
|
-
@@data.keys
|
26
|
-
end
|
27
|
-
|
28
|
-
def record(topic, secs)
|
29
|
-
d = data(topic)
|
30
|
-
d['msgs'] += 1
|
31
|
-
d['time'] += secs
|
32
|
-
end
|
33
|
-
|
34
|
-
def calc_utilization(topic, t2=nil)
|
35
|
-
d = data(topic)
|
36
|
-
t1 = @@start
|
37
|
-
t2 ||= Time.now
|
38
|
-
secs = (t2 - t1)
|
39
|
-
secs = 1 if secs <= 0.0
|
40
|
-
if d['msgs'] == 0
|
41
|
-
avg = 0.0
|
42
|
-
else
|
43
|
-
avg = d['time'] / d['msgs']
|
44
|
-
end
|
45
|
-
utilization = d['time'] / secs
|
46
|
-
{
|
47
|
-
:avg => avg,
|
48
|
-
:secs => secs,
|
49
|
-
:utilization => utilization,
|
50
|
-
:msgs => d['msgs'],
|
51
|
-
:msgs_per_sec => d['msgs'] / secs
|
52
|
-
}
|
53
|
-
end
|
54
|
-
|
55
|
-
def monitor(topic, opts={})
|
56
|
-
topic = 'temporary' if opts[:temp]
|
57
|
-
|
58
|
-
t1 = Time.now
|
59
|
-
begin
|
60
|
-
yield if block_given?
|
61
|
-
ensure
|
62
|
-
t2 = Time.now
|
63
|
-
record(topic, t2 - t1)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def report
|
68
|
-
data = {}
|
69
|
-
t2 = Time.now
|
70
|
-
topics.each do |topic|
|
71
|
-
data[topic] = calc_utilization(topic, t2)
|
72
|
-
end
|
73
|
-
|
74
|
-
summary = { :avg => 0.0, :utilization => 0.0, :msgs => 0, :msgs_per_sec => 0.0, :secs => 0.0 }
|
75
|
-
data.each do |topic, d|
|
76
|
-
summary[:utilization] += d[:utilization]
|
77
|
-
summary[:msgs] += d[:msgs]
|
78
|
-
summary[:msgs_per_sec] += d[:msgs_per_sec]
|
79
|
-
summary[:avg] += d[:avg]
|
80
|
-
summary[:secs] += d[:secs]
|
81
|
-
end
|
82
|
-
if data.size < 1
|
83
|
-
summary[:avg] = 0.0
|
84
|
-
else
|
85
|
-
summary[:avg] /= data.size
|
86
|
-
end
|
87
|
-
|
88
|
-
{ :summary => summary, :data => data }
|
89
|
-
end
|
90
|
-
end
|
data/test/base.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'rush'
|
2
|
-
|
3
|
-
def publish(message, payload={})
|
4
|
-
Droid.new('Sender', RabbitmqSetup.credentials) do |d|
|
5
|
-
d.publish(message, payload)
|
6
|
-
Droid.stop_safe
|
7
|
-
end
|
8
|
-
sleep(0.1)
|
9
|
-
end
|
10
|
-
|
11
|
-
$exchange = nil
|
12
|
-
$mutex = Mutex.new
|
13
|
-
def exchange
|
14
|
-
$mutex.synchronize { $exchange }
|
15
|
-
end
|
16
|
-
def save_in_exchange(v)
|
17
|
-
$mutex.synchronize { $exchange = v }
|
18
|
-
end
|
19
|
-
|
20
|
-
module RabbitmqSetup
|
21
|
-
extend self
|
22
|
-
|
23
|
-
def credentials
|
24
|
-
{
|
25
|
-
:vhost => '/test',
|
26
|
-
:host => 'localhost',
|
27
|
-
:user => 'test',
|
28
|
-
:pass => 'test'
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
def run_rabbitmqctl(command)
|
33
|
-
Rush::Box.new.bash "rabbitmqctl #{command}"
|
34
|
-
rescue Rush::BashFailed => e
|
35
|
-
raise unless e.message.match(/already_exists/)
|
36
|
-
end
|
37
|
-
|
38
|
-
def run
|
39
|
-
run_rabbitmqctl("add_vhost #{credentials[:vhost]}")
|
40
|
-
run_rabbitmqctl("add_user #{credentials[:user]} #{credentials[:pass]}")
|
41
|
-
run_rabbitmqctl("map_user_vhost #{credentials[:user]} #{credentials[:vhost]}")
|
42
|
-
end
|
43
|
-
end
|
data/test/droid_test.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../lib/droid'
|
2
|
-
require File.dirname(__FILE__) + '/base'
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'thread'
|
6
|
-
require 'bacon'
|
7
|
-
|
8
|
-
RabbitmqSetup.run
|
9
|
-
|
10
|
-
Bacon.summary_on_exit
|
11
|
-
|
12
|
-
Thread.new do
|
13
|
-
Droid.new('Test Droid', RabbitmqSetup.credentials) do |d|
|
14
|
-
d.on_error do |msg, e|
|
15
|
-
save_in_exchange(e)
|
16
|
-
end
|
17
|
-
|
18
|
-
d.before_filter do |msg|
|
19
|
-
if to_save = msg[:save_in_before_filter]
|
20
|
-
save_in_exchange(to_save)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
d.listen4('save.msg') do |msg|
|
25
|
-
save_in_exchange(msg)
|
26
|
-
end
|
27
|
-
|
28
|
-
d.listen4('do.nothing') do |msg|
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
sleep(2) # wait until droid is up
|
34
|
-
describe Droid do
|
35
|
-
before do
|
36
|
-
save_in_exchange(nil)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "sends and receives simple messages" do
|
40
|
-
publish('save.msg')
|
41
|
-
exchange.should.not == nil
|
42
|
-
end
|
43
|
-
|
44
|
-
it "sends messages with params" do
|
45
|
-
publish('save.msg', :test => 1)
|
46
|
-
exchange[:test].should == 1
|
47
|
-
end
|
48
|
-
|
49
|
-
it "accepts before filters" do
|
50
|
-
publish('do.nothing', :save_in_before_filter => 42)
|
51
|
-
exchange.should == 42
|
52
|
-
end
|
53
|
-
end
|
data/test/heroku_droid_test.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../lib/heroku_droid'
|
2
|
-
require File.dirname(__FILE__) + '/base'
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'thread'
|
6
|
-
require 'bacon'
|
7
|
-
|
8
|
-
Bacon.summary_on_exit
|
9
|
-
|
10
|
-
Thread.new do
|
11
|
-
HerokuDroid.new('Test Heroku Droid') do |d|
|
12
|
-
d.stats do
|
13
|
-
"some stats"
|
14
|
-
end
|
15
|
-
|
16
|
-
d.listen4('pong') do |msg|
|
17
|
-
save_in_exchange('worked') if msg['notes'] == 'some stats'
|
18
|
-
end
|
19
|
-
|
20
|
-
d.listen4('save.msg') do |msg|
|
21
|
-
save_in_exchange(msg)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
sleep(2) # wait until droid is up
|
27
|
-
describe HerokuDroid do
|
28
|
-
before do
|
29
|
-
save_in_exchange(nil)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "sends and receives simple messages" do
|
33
|
-
publish('save.msg')
|
34
|
-
exchange.should.not == nil
|
35
|
-
end
|
36
|
-
|
37
|
-
it "responds to ping with a pong message and instances/droid stats filled in" do
|
38
|
-
publish('ping')
|
39
|
-
sleep 3
|
40
|
-
exchange.should == 'worked'
|
41
|
-
end
|
42
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'spec/rake/spectask'
|
3
|
-
|
4
|
-
desc "Run all specs"
|
5
|
-
Spec::Rake::SpecTask.new('spec') do |t|
|
6
|
-
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
7
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
8
|
-
end
|
9
|
-
|
10
|
-
task :default => :spec
|
11
|
-
|
12
|
-
###
|
13
|
-
|
14
|
-
require 'rake'
|
15
|
-
require 'rake/testtask'
|
16
|
-
require 'rake/clean'
|
17
|
-
require 'rake/gempackagetask'
|
18
|
-
require 'rake/rdoctask'
|
19
|
-
require 'fileutils'
|
20
|
-
|
21
|
-
version = "0.1"
|
22
|
-
name = "logger_client"
|
23
|
-
|
24
|
-
spec = Gem::Specification.new do |s|
|
25
|
-
s.name = name
|
26
|
-
s.version = version
|
27
|
-
s.summary = "Client for Heroku logger"
|
28
|
-
s.author = "Pedro Belo"
|
29
|
-
s.email = "pedro@heroku.com"
|
30
|
-
|
31
|
-
s.platform = Gem::Platform::RUBY
|
32
|
-
s.has_rdoc = false
|
33
|
-
|
34
|
-
s.files = %w(Rakefile init.rb) + Dir.glob("{lib,spec}/**/*")
|
35
|
-
|
36
|
-
s.require_path = "lib"
|
37
|
-
|
38
|
-
s.add_dependency('rest-client', '>=0.6.2')
|
39
|
-
end
|
40
|
-
|
41
|
-
Rake::GemPackageTask.new(spec) do |p|
|
42
|
-
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
43
|
-
end
|
44
|
-
|
45
|
-
task :install => [ :package ] do
|
46
|
-
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
47
|
-
end
|
48
|
-
|
49
|
-
task :uninstall => [ :clean ] do
|
50
|
-
sh %{sudo gem uninstall #{name}}
|
51
|
-
end
|
52
|
-
|
53
|
-
CLEAN.include [ 'pkg', '*.gem', '.config' ]
|
@@ -1 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/lib/logger_client'
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'lib/logger_client'
|
2
|
-
|
3
|
-
Log.configure { |c| c.component = 'test' }
|
4
|
-
|
5
|
-
Log.notice "without event"
|
6
|
-
|
7
|
-
Log.event "event 1" do
|
8
|
-
Log.debug "started"
|
9
|
-
Log.notice "doing something"
|
10
|
-
Log.warning "almost failed"
|
11
|
-
end
|
12
|
-
|
13
|
-
Log.debug "without event"
|
14
|
-
|
15
|
-
Log.event "the great crash" do
|
16
|
-
Log.notice "doing something that will crash (except a backtrace below)"
|
17
|
-
4/0
|
18
|
-
end
|