droid 0.9.0 → 0.9.1
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/README.md +34 -0
- metadata +12 -15
- data/bin/conf +0 -31
- data/speaker/droid_speaker.rb +0 -79
- data/speaker/speak +0 -33
- data/speaker/test.rb +0 -58
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
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
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: droid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 57
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 1
|
10
|
+
version: 0.9.1
|
11
11
|
platform: ruby
|
12
12
|
authors: []
|
13
13
|
|
@@ -15,8 +15,8 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06
|
19
|
-
default_executable:
|
18
|
+
date: 2010-07-06 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: json_pure
|
@@ -48,12 +48,12 @@ dependencies:
|
|
48
48
|
version_requirements: *id002
|
49
49
|
description:
|
50
50
|
email:
|
51
|
-
executables:
|
52
|
-
- conf
|
53
|
-
extensions: []
|
51
|
+
executables: []
|
54
52
|
|
55
|
-
|
53
|
+
extensions: []
|
56
54
|
|
55
|
+
extra_rdoc_files:
|
56
|
+
- README.md
|
57
57
|
files:
|
58
58
|
- lib/droid.rb
|
59
59
|
- lib/droid/sync.rb
|
@@ -62,18 +62,15 @@ files:
|
|
62
62
|
- lib/memcache_cluster.rb
|
63
63
|
- lib/stats.rb
|
64
64
|
- lib/utilization.rb
|
65
|
-
- speaker/droid_speaker.rb
|
66
|
-
- speaker/speak
|
67
|
-
- speaker/test.rb
|
68
65
|
- vendor/logger_client/Rakefile
|
69
66
|
- vendor/logger_client/init.rb
|
70
67
|
- vendor/logger_client/lib/logger_client.rb
|
71
68
|
- vendor/logger_client/test.rb
|
72
|
-
-
|
69
|
+
- README.md
|
73
70
|
- test/base.rb
|
74
71
|
- test/droid_test.rb
|
72
|
+
- test/heroku_droid_test.rb
|
75
73
|
- test/wait_for_port_test.rb
|
76
|
-
- bin/conf
|
77
74
|
has_rdoc: true
|
78
75
|
homepage:
|
79
76
|
licenses: []
|
@@ -109,7 +106,7 @@ signing_key:
|
|
109
106
|
specification_version: 3
|
110
107
|
summary: AMQP wrapper
|
111
108
|
test_files:
|
112
|
-
- test/heroku_droid_test.rb
|
113
109
|
- test/base.rb
|
114
110
|
- test/droid_test.rb
|
111
|
+
- test/heroku_droid_test.rb
|
115
112
|
- test/wait_for_port_test.rb
|
data/bin/conf
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
def wait_for_tcp_port(port, options={})
|
5
|
-
options[:timeout] ||= 30
|
6
|
-
options[:host] ||= "localhost"
|
7
|
-
|
8
|
-
options[:timeout].times do
|
9
|
-
begin
|
10
|
-
x = TCPSocket.new(options[:host], port)
|
11
|
-
x.close
|
12
|
-
return
|
13
|
-
rescue
|
14
|
-
sleep 1
|
15
|
-
next
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
raise "#{options[:host]}:#{port} did not come up after #{options[:timeout]} seconds"
|
20
|
-
end
|
21
|
-
|
22
|
-
puts "Waiting for RabbitMQ"
|
23
|
-
wait_for_tcp_port(5672)
|
24
|
-
|
25
|
-
puts `rabbitmqctl add_vhost /heroku`
|
26
|
-
|
27
|
-
%w[hermes core].each do |agent|
|
28
|
-
puts `rabbitmqctl add_user #{agent} thisisheroku!`
|
29
|
-
puts `rabbitmqctl set_permissions -p /heroku #{agent} \".*\" \".*\" \".*\"`
|
30
|
-
end
|
31
|
-
|
data/speaker/droid_speaker.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/json_pure-1.1.3/lib'
|
2
|
-
require 'json'
|
3
|
-
require 'drb'
|
4
|
-
require 'timeout'
|
5
|
-
|
6
|
-
class DroidSpeaker
|
7
|
-
|
8
|
-
def self.drb_connect(port)
|
9
|
-
DRb.start_service()
|
10
|
-
@drb = DRbObject.new(nil,"druby://localhost:#{port}")
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.drb_cast(topic, payload, &p)
|
14
|
-
@drb.publish(topic, payload, &p)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.drb_call(topic, payload)
|
18
|
-
## this is the best stupid trick I could think of the force blocking
|
19
|
-
lock = Thread.new { sleep 9999 }
|
20
|
-
@r = nil
|
21
|
-
@drb.publish(topic, payload) do |result|
|
22
|
-
@r = result
|
23
|
-
lock.kill
|
24
|
-
end
|
25
|
-
lock.join
|
26
|
-
@r
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.send(topic, payload, &p)
|
30
|
-
i = new
|
31
|
-
i.send(topic, payload, &p)
|
32
|
-
i.flush
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.start
|
36
|
-
i = new
|
37
|
-
yield(i)
|
38
|
-
i.flush
|
39
|
-
end
|
40
|
-
|
41
|
-
def initialize
|
42
|
-
@message = nil
|
43
|
-
@callback = nil
|
44
|
-
end
|
45
|
-
|
46
|
-
def send(topic, payload, &blk)
|
47
|
-
if defined?(Log) and event_id = Log.default_options[:event_id]
|
48
|
-
payload.merge!(:event_hash => event_id)
|
49
|
-
end
|
50
|
-
|
51
|
-
attrs = { :topic => topic, :payload => payload }
|
52
|
-
if blk # this message should be replied
|
53
|
-
attrs.merge!(:has_reply => true)
|
54
|
-
@callback = blk
|
55
|
-
end
|
56
|
-
@message = attrs
|
57
|
-
end
|
58
|
-
|
59
|
-
class MessageError < RuntimeError; end
|
60
|
-
|
61
|
-
def flush
|
62
|
-
out = ''
|
63
|
-
IO.popen("#{File.dirname(__FILE__)}/../speaker/speak 2>/dev/null", 'w+') do |io|
|
64
|
-
io.puts @message.to_json
|
65
|
-
out = io.read
|
66
|
-
end
|
67
|
-
begin
|
68
|
-
response = JSON.parse(out)
|
69
|
-
response.delete('event_hash')
|
70
|
-
@callback.call(response) if @callback
|
71
|
-
rescue JSON::ParserError
|
72
|
-
if out.include?('Timeout::Error')
|
73
|
-
raise Timeout::Error, "Timed out while waiting for a response for #{@message[:topic]}"
|
74
|
-
else
|
75
|
-
raise MessageError, out
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/speaker/speak
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
begin
|
4
|
-
$:.unshift '/usr/local/droid/lib'
|
5
|
-
require 'heroku_droid'
|
6
|
-
|
7
|
-
msg = JSON.load(gets)
|
8
|
-
|
9
|
-
Timeout.timeout(10) do
|
10
|
-
HerokuDroid.new('Droid Speaker', :standard_topics => false) do |droid|
|
11
|
-
if msg['has_reply']
|
12
|
-
@event_hash = msg['payload']['event_hash'] ||= Droid::Basic.new(droid).event_hash
|
13
|
-
droid.listen4('event.error') do |d|
|
14
|
-
if d.headers[:event_hash] == @event_hash
|
15
|
-
puts "Message #{msg['topic']} failed: see event #{@event_hash}"
|
16
|
-
Droid.stop_safe
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
droid.publish(msg['topic'], msg['payload']) do |d|
|
21
|
-
puts d.params.to_json
|
22
|
-
Droid.stop_safe
|
23
|
-
end
|
24
|
-
else
|
25
|
-
droid.publish(msg['topic'], msg['payload'])
|
26
|
-
puts({}.to_json)
|
27
|
-
Droid.stop_safe
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
rescue Object => e
|
32
|
-
puts "#{e.class}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
33
|
-
end
|
data/speaker/test.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
Thread.new do
|
2
|
-
require File.dirname(__FILE__) + '/../lib/heroku_droid'
|
3
|
-
HerokuDroid.new('Droid speaker test') do |droid|
|
4
|
-
droid.listen4('speaker.test') do |msg|
|
5
|
-
if msg['marco'] == 1
|
6
|
-
puts "Got 'marco', returning 'polo'..."
|
7
|
-
msg.reply('polo' => 1)
|
8
|
-
else
|
9
|
-
puts "Bad payload"
|
10
|
-
msg.reply('error' => 1)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
droid.listen4('speaker.raise') do |msg|
|
14
|
-
raise "droid raised exception"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
sleep 2
|
20
|
-
|
21
|
-
require File.dirname(__FILE__) + '/droid_speaker'
|
22
|
-
|
23
|
-
puts "\nTest 1: Sending simple message"
|
24
|
-
DroidSpeaker.send('fire.and.forget', 'val' => 1)
|
25
|
-
puts "\tSuccess!"
|
26
|
-
|
27
|
-
puts "\nTest 2: Sending and receiving response"
|
28
|
-
DroidSpeaker.send('speaker.test', 'marco' => 1) do |r|
|
29
|
-
if r['polo'] == 1
|
30
|
-
puts "\tSuccess!"
|
31
|
-
else
|
32
|
-
puts "\tFailed, result: #{r.inspect}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
puts "\nTest 3: Exceptions"
|
37
|
-
begin
|
38
|
-
DroidSpeaker.send('speaker.raise', {}) do |r|
|
39
|
-
puts "\tFailed, expected exception"
|
40
|
-
end
|
41
|
-
rescue DroidSpeaker::MessageError => e
|
42
|
-
if e.message =~ /event \w+/
|
43
|
-
puts "\tSuccess!"
|
44
|
-
else
|
45
|
-
puts "\tFailed, droid speaker raised #{e.message}"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
puts "\nTest 4: Timeout"
|
50
|
-
begin
|
51
|
-
DroidSpeaker.send('dont.reply', {}) do |r|
|
52
|
-
puts "\tFailed, didnt expect a response"
|
53
|
-
end
|
54
|
-
rescue Timeout::Error
|
55
|
-
puts "\tSuccess!"
|
56
|
-
rescue Exception => e
|
57
|
-
puts "\tFailed, expected Timeout::Error, got #{e.class.name}"
|
58
|
-
end
|