droid 1.0.2pre → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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