droid 1.0.2pre → 1.0.2

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/Rakefile CHANGED
@@ -2,35 +2,35 @@ require 'rubygems'
2
2
  require 'rake'
3
3
 
4
4
  begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "droid"
8
- gem.summary = %Q{AMQP Wrapper Library}
9
- gem.description = %Q{Easy to use AMQP Library with constructs for typical usage patterns}
10
- gem.email = "ricardo@heroku.com"
11
- gem.homepage = "http://heroku.com"
12
- gem.authors = ["Ricardo Chimal, Jr."]
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "droid"
8
+ gem.summary = %Q{AMQP Wrapper Library}
9
+ gem.description = %Q{Easy to use AMQP Library with constructs for typical usage patterns}
10
+ gem.email = "ricardo@heroku.com"
11
+ gem.homepage = "http://heroku.com"
12
+ gem.authors = ["Ricardo Chimal, Jr."]
13
13
 
14
- gem.add_development_dependency "baconmocha", ">= 0"
14
+ gem.add_development_dependency "baconmocha", ">= 0"
15
15
 
16
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
- gem.add_dependency 'json_pure', '>= 1.2.0'
18
- gem.add_dependency 'rest-client', '>= 1.2.0'
19
- gem.add_dependency 'amqp', '0.6.7'
20
- gem.add_dependency 'bunny', '~> 0.6.0'
21
- gem.add_dependency 'SystemTimer', '~> 1.2.0'
22
- gem.add_dependency 'eventmachine_httpserver', '0.2.0'
23
- end
24
- Jeweler::GemcutterTasks.new
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ gem.add_dependency 'json_pure', '>= 1.2.0'
18
+ gem.add_dependency 'rest-client', '>= 1.2.0'
19
+ gem.add_dependency 'amqp', '0.6.7'
20
+ gem.add_dependency 'bunny', '~> 0.6.0'
21
+ gem.add_dependency 'SystemTimer', '~> 1.2.0'
22
+ gem.add_dependency 'eventmachine_httpserver', '0.2.0'
23
+ end
24
+ Jeweler::GemcutterTasks.new
25
25
  rescue LoadError
26
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
27
27
  end
28
28
 
29
29
  require 'rake/testtask'
30
30
  Rake::TestTask.new(:spec) do |spec|
31
- spec.libs << 'lib' << 'spec'
32
- spec.pattern = 'spec/**/*_spec.rb'
33
- spec.verbose = true
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.verbose = true
34
34
  end
35
35
 
36
36
  task :spec => :check_dependencies
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.2pre
1
+ 1.0.2
data/bin/bleedq CHANGED
@@ -13,7 +13,7 @@ q = b.queue(queue_name)
13
13
  puts "Bleeding queue #{queue_name}"
14
14
 
15
15
  while ((msg = q.pop)[:payload] != :queue_empty) do
16
- pp msg
16
+ pp msg
17
17
  end
18
18
 
19
19
  puts "done."
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{droid}
8
- s.version = "1.0.2pre"
8
+ s.version = "1.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ricardo Chimal, Jr."]
12
- s.date = %q{2010-11-12}
12
+ s.date = %q{2011-07-29}
13
13
  s.default_executable = %q{bleedq}
14
14
  s.description = %q{Easy to use AMQP Library with constructs for typical usage patterns}
15
15
  s.email = %q{ricardo@heroku.com}
@@ -2,24 +2,24 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
2
2
  require 'droid'
3
3
 
4
4
  def log
5
- Droid.log
5
+ Droid.log
6
6
  end
7
7
 
8
8
  Droid.new('Example Reply') do |droid|
9
- droid.worker('example.target').subscribe do |req|
10
- log.debug "headers: #{req.header.headers.inspect}"
11
- log.debug "event_hash should be woot -> #{req.droid_headers[:event_hash]}"
12
- req.reply(:target_received_at => Time.now.to_i)
13
- req.ack
14
- end
9
+ droid.worker('example.target').subscribe do |req|
10
+ log.debug "headers: #{req.header.headers.inspect}"
11
+ log.debug "event_hash should be woot -> #{req.droid_headers[:event_hash]}"
12
+ req.reply(:target_received_at => Time.now.to_i)
13
+ req.ack
14
+ end
15
15
 
16
- droid.listener('example.check.target').subscribe do |req|
17
- req.publish('example.target', { :checking => Time.now.to_i }) do |req2|
18
- log.debug "event_hash should be woot -> #{req2.droid_headers[:event_hash]}"
19
- log.info "We're done checking!"
20
- Droid.stop_safe
21
- end
22
- end
16
+ droid.listener('example.check.target').subscribe do |req|
17
+ req.publish('example.target', { :checking => Time.now.to_i }) do |req2|
18
+ log.debug "event_hash should be woot -> #{req2.droid_headers[:event_hash]}"
19
+ log.info "We're done checking!"
20
+ Droid.stop_safe
21
+ end
22
+ end
23
23
 
24
- droid.timer(2) { Droid.publish('example.check.target', {:sent_at => Time.now.to_i}, {:event_hash => "woot"}) }
24
+ droid.timer(2) { Droid.publish('example.check.target', {:sent_at => Time.now.to_i}, {:event_hash => "woot"}) }
25
25
  end
@@ -2,21 +2,21 @@ $:.unshift File.dirname(__FILE__) + '/../lib/'
2
2
  require 'heroku_droid'
3
3
 
4
4
  def log
5
- Droid.log
5
+ Droid.log
6
6
  end
7
7
 
8
8
  HerokuDroid.new('Example Reply') do |droid|
9
- droid.worker('example.target').subscribe do |req|
10
- req.reply(:target_received_at => Time.now.to_i)
11
- req.ack
12
- end
9
+ droid.worker('example.target').subscribe do |req|
10
+ req.reply(:target_received_at => Time.now.to_i)
11
+ req.ack
12
+ end
13
13
 
14
- droid.listener('example.check.target').subscribe do |req|
15
- req.publish('example.target', { :checking => Time.now.to_i }) do |req2|
16
- log.info "We're done checking!"
17
- Droid.stop_safe
18
- end
19
- end
14
+ droid.listener('example.check.target').subscribe do |req|
15
+ req.publish('example.target', { :checking => Time.now.to_i }) do |req2|
16
+ log.info "We're done checking!"
17
+ Droid.stop_safe
18
+ end
19
+ end
20
20
 
21
- EM.add_timer(2) { Droid.publish('example.check.target', :sent_at => Time.now.to_i ) }
21
+ EM.add_timer(2) { Droid.publish('example.check.target', :sent_at => Time.now.to_i ) }
22
22
  end
@@ -2,22 +2,22 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
2
2
  require 'droid'
3
3
 
4
4
  def log
5
- Droid.log
5
+ Droid.log
6
6
  end
7
7
 
8
8
  if ARGV[0] == 'listen'
9
- Droid.new('Example Worker') do |droid|
10
- droid.worker('example.bunny.worker').subscribe do |req|
11
- req.ack
12
- log.info "Work done, replying..."
13
- req.reply(:t => Time.now.to_i)
14
- end
15
-
16
- droid.listener('example.bunny.listener').subscribe do |req|
17
- log.info "I heard #{req['t']}"
18
- end
19
- end
20
- exit(0)
9
+ Droid.new('Example Worker') do |droid|
10
+ droid.worker('example.bunny.worker').subscribe do |req|
11
+ req.ack
12
+ log.info "Work done, replying..."
13
+ req.reply(:t => Time.now.to_i)
14
+ end
15
+
16
+ droid.listener('example.bunny.listener').subscribe do |req|
17
+ log.info "I heard #{req['t']}"
18
+ end
19
+ end
20
+ exit(0)
21
21
  end
22
22
 
23
23
 
@@ -2,7 +2,7 @@ $:.unshift File.dirname(__FILE__) + '/../lib'
2
2
  require 'droid'
3
3
 
4
4
  def log
5
- Droid.log
5
+ Droid.log
6
6
  end
7
7
 
8
8
  @gum_chews = 0
@@ -10,49 +10,49 @@ end
10
10
 
11
11
  Droid.new('Example Worker') do |droid|
12
12
 
13
- # auto acks the message
14
- @gum = droid.worker('example.chew.gum').subscribe do |req|
15
- log.info "flavor: #{req['flavor']}, packs: #{req['packs']}"
16
- log.info req.msg.inspect
17
- log.info req.droid_headers
18
-
19
- @gum_chews += 1
20
- end
21
-
22
- # explicit ack
23
- @toffee = droid.worker('example.chew.toffee').subscribe(:auto_ack => false) do |req|
24
- log.info "flavor: #{req['flavor']}"
25
- log.info req.msg.inspect
26
- log.info req.droid_headers
27
-
28
- req.ack
29
-
30
- @toffee_chews += 1
31
- end
32
-
33
- droid.periodic_timer(2) do
34
- log.debug "checking gum & toffee chews"
35
-
36
- if @gum_chews == 3 && @gum
37
- @gum.destroy
38
- @gum = nil
39
- end
40
-
41
- if @toffee_chews == 2 && @toffee
42
- @toffee.destroy
43
- @toffee = nil
44
- end
45
-
46
- if @toffee.nil? && @gum.nil?
47
- Droid.stop_safe
48
- end
49
- end
50
-
51
- droid.timer(2) do
52
- droid.publish('example.chew.gum', :flavor => 'spearmint', :packs => 2)
53
- droid.publish('example.chew.gum', :flavor => 'bubblegum', :packs => 3)
54
- droid.publish('example.chew.gum', :flavor => 'peppermint', :packs => 1)
55
- droid.publish('example.chew.toffee', :flavor => 'caramel')
56
- droid.publish('example.chew.toffee', :flavor => 'licorish')
57
- end
13
+ # auto acks the message
14
+ @gum = droid.worker('example.chew.gum').subscribe do |req|
15
+ log.info "flavor: #{req['flavor']}, packs: #{req['packs']}"
16
+ log.info req.msg.inspect
17
+ log.info req.droid_headers
18
+
19
+ @gum_chews += 1
20
+ end
21
+
22
+ # explicit ack
23
+ @toffee = droid.worker('example.chew.toffee').subscribe(:auto_ack => false) do |req|
24
+ log.info "flavor: #{req['flavor']}"
25
+ log.info req.msg.inspect
26
+ log.info req.droid_headers
27
+
28
+ req.ack
29
+
30
+ @toffee_chews += 1
31
+ end
32
+
33
+ droid.periodic_timer(2) do
34
+ log.debug "checking gum & toffee chews"
35
+
36
+ if @gum_chews == 3 && @gum
37
+ @gum.destroy
38
+ @gum = nil
39
+ end
40
+
41
+ if @toffee_chews == 2 && @toffee
42
+ @toffee.destroy
43
+ @toffee = nil
44
+ end
45
+
46
+ if @toffee.nil? && @gum.nil?
47
+ Droid.stop_safe
48
+ end
49
+ end
50
+
51
+ droid.timer(2) do
52
+ droid.publish('example.chew.gum', :flavor => 'spearmint', :packs => 2)
53
+ droid.publish('example.chew.gum', :flavor => 'bubblegum', :packs => 3)
54
+ droid.publish('example.chew.gum', :flavor => 'peppermint', :packs => 1)
55
+ droid.publish('example.chew.toffee', :flavor => 'caramel')
56
+ droid.publish('example.chew.toffee', :flavor => 'licorish')
57
+ end
58
58
  end
@@ -3,7 +3,7 @@ require 'amqp'
3
3
  require 'mq'
4
4
 
5
5
  if !defined?(JSON) && !defined?(JSON_LOADED)
6
- require 'json/pure'
6
+ require 'json/pure'
7
7
  end
8
8
 
9
9
  require 'droid/monkey'
@@ -16,126 +16,126 @@ require 'droid/queue'
16
16
  require 'droid/em'
17
17
 
18
18
  class Droid
19
- def self.version
20
- @@version ||= File.read(File.dirname(__FILE__) + '/../VERSION').strip
21
- end
22
-
23
- def self.name
24
- @@name
25
- end
26
-
27
- def self.name=(name)
28
- @@name = name
29
- end
30
-
31
- def self.log=(log)
32
- @@log = log
33
- end
34
-
35
- def self.log
36
- @@log ||= begin
37
- require 'logger'
38
- Logger.class_eval <<EORUBY
39
- alias_method :notice, :info
40
-
41
- alias_method :error_og, :error
42
- def error(err, opts={})
43
- e = opts[:exception]
44
- if e.respond_to?(:backtrace)
45
- err += "\n" + e.backtrace.join("\n ")
46
- end
47
- error_og(err)
48
- end
19
+ def self.version
20
+ @@version ||= File.read(File.dirname(__FILE__) + '/../VERSION').strip
21
+ end
22
+
23
+ def self.name
24
+ @@name
25
+ end
26
+
27
+ def self.name=(name)
28
+ @@name = name
29
+ end
30
+
31
+ def self.log=(log)
32
+ @@log = log
33
+ end
34
+
35
+ def self.log
36
+ @@log ||= begin
37
+ require 'logger'
38
+ Logger.class_eval <<EORUBY
39
+ alias_method :notice, :info
40
+
41
+ alias_method :error_og, :error
42
+ def error(err, opts={})
43
+ e = opts[:exception]
44
+ if e.respond_to?(:backtrace)
45
+ err += "\n" + e.backtrace.join("\n ")
46
+ end
47
+ error_og(err)
48
+ end
49
49
  EORUBY
50
- Logger.new($stderr)
51
- end
52
- end
53
-
54
- def self.default_config
55
- uri = URI.parse(ENV["AMQP_URL"] || 'amqp://guest:guest@localhost:5672/')
56
- {
57
- :vhost => uri.path,
58
- :host => uri.host,
59
- :user => uri.user,
60
- :port => uri.port || 5672,
61
- :pass => uri.password
62
- }
63
- rescue Object => e
64
- raise "invalid AMQP_URL: (#{uri.inspect}) #{e.class} -> #{e.message}"
65
- end
66
-
67
- def self.start(opts={})
68
- config = opts[:config] || self.default_config
69
-
70
- wait_for_tcp_port(config[:host], config[:port])
71
-
72
- begin
73
- ::Signal.trap('INT') { ::AMQP.stop{ ::EM.stop } }
74
- ::Signal.trap('TERM'){ ::AMQP.stop{ ::EM.stop } }
75
-
76
- ::AMQP.start(config) do
77
- yield if block_given?
78
- end
79
- rescue ::AMQP::Error => e
80
- log.debug "Caught #{e.class}, sleeping to avoid inittab thrashing"
81
- sleep 5
82
- log.debug "Done."
83
- raise
84
- end
85
- end
86
-
87
- def self.stop_safe
88
- ::EM.add_timer(0.2) { ::AMQP.stop { ::EM.stop } }
89
- end
90
-
91
- def self.closing?
92
- ::AMQP.closing?
93
- end
94
-
95
- def self.handle_error(err)
96
- log.error "#{err.class}: #{err.message}", :exception => err
97
- end
98
-
99
- def self.wait_for_tcp_port(host, port, opts={})
100
- require 'system_timer'
101
- require 'socket'
102
-
103
- opts[:retries] ||= 6
104
- opts[:timeout] ||= 5
105
-
106
- opts[:retries].times do
107
- begin
108
- SystemTimer::timeout(opts[:timeout]) do
109
- TCPSocket.new(host.to_s, port).close
110
- end
111
- return
112
- rescue Object => e
113
- log.info "#{host}:#{port} not available, waiting... #{e.class}: #{e.message}"
114
- sleep 1
115
- end
116
- end
117
-
118
- raise "#{host}:#{port} did not come up after #{opts[:retries]} retries"
119
- end
120
-
121
- def initialize(name, opts={})
122
- log.info "=== #{name} droid initializing"
123
-
124
- self.class.name = name
125
- self.class.start do
126
- yield self if block_given?
127
- end
128
- end
129
-
130
- def publish(*args)
131
- Droid.publish(*args)
132
- end
133
-
134
- def log
135
- self.class.log
136
- end
137
-
138
- include Droid::QueueMethods
139
- include Droid::BackwardsCompatibleMethods
140
- include Droid::EMTimerUtils
50
+ Logger.new($stderr)
51
+ end
52
+ end
53
+
54
+ def self.default_config
55
+ uri = URI.parse(ENV["AMQP_URL"] || 'amqp://guest:guest@localhost:5672/')
56
+ {
57
+ :vhost => uri.path,
58
+ :host => uri.host,
59
+ :user => uri.user,
60
+ :port => uri.port || 5672,
61
+ :pass => uri.password
62
+ }
63
+ rescue Object => e
64
+ raise "invalid AMQP_URL: (#{uri.inspect}) #{e.class} -> #{e.message}"
65
+ end
66
+
67
+ def self.start(opts={})
68
+ config = opts[:config] || self.default_config
69
+
70
+ wait_for_tcp_port(config[:host], config[:port])
71
+
72
+ begin
73
+ ::Signal.trap('INT') { ::AMQP.stop{ ::EM.stop } }
74
+ ::Signal.trap('TERM'){ ::AMQP.stop{ ::EM.stop } }
75
+
76
+ ::AMQP.start(config) do
77
+ yield if block_given?
78
+ end
79
+ rescue ::AMQP::Error => e
80
+ log.debug "Caught #{e.class}, sleeping to avoid inittab thrashing"
81
+ sleep 5
82
+ log.debug "Done."
83
+ raise
84
+ end
85
+ end
86
+
87
+ def self.stop_safe
88
+ ::EM.add_timer(0.2) { ::AMQP.stop { ::EM.stop } }
89
+ end
90
+
91
+ def self.closing?
92
+ ::AMQP.closing?
93
+ end
94
+
95
+ def self.handle_error(err)
96
+ log.error "#{err.class}: #{err.message}", :exception => err
97
+ end
98
+
99
+ def self.wait_for_tcp_port(host, port, opts={})
100
+ require 'system_timer'
101
+ require 'socket'
102
+
103
+ opts[:retries] ||= 6
104
+ opts[:timeout] ||= 5
105
+
106
+ opts[:retries].times do
107
+ begin
108
+ SystemTimer::timeout(opts[:timeout]) do
109
+ TCPSocket.new(host.to_s, port).close
110
+ end
111
+ return
112
+ rescue Object => e
113
+ log.info "#{host}:#{port} not available, waiting... #{e.class}: #{e.message}"
114
+ sleep 1
115
+ end
116
+ end
117
+
118
+ raise "#{host}:#{port} did not come up after #{opts[:retries]} retries"
119
+ end
120
+
121
+ def initialize(name, opts={})
122
+ log.info "=== #{name} droid initializing"
123
+
124
+ self.class.name = name
125
+ self.class.start do
126
+ yield self if block_given?
127
+ end
128
+ end
129
+
130
+ def publish(*args)
131
+ Droid.publish(*args)
132
+ end
133
+
134
+ def log
135
+ self.class.log
136
+ end
137
+
138
+ include Droid::QueueMethods
139
+ include Droid::BackwardsCompatibleMethods
140
+ include Droid::EMTimerUtils
141
141
  end