carnivore 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # v0.1.4
2
+ * Update `Source#send` to `Source#transmit`
3
+ * Add common util module for logging
4
+ * Allow SQS queues to be provided in named Hash form
5
+ * Allow sending to named SQS queues
6
+ * Make automatic response optional on HTTP source
7
+ * Use `Carnivore::Message` instead of bare hash for message passing
8
+
1
9
  # v0.1.2
2
10
  * Allow ARN based queue endpoints for SQS
3
11
 
@@ -1,3 +1,5 @@
1
+ require 'carnivore/utils'
2
+
1
3
  module Carnivore
2
4
  class Callback
3
5
 
@@ -6,6 +8,7 @@ module Carnivore
6
8
  end
7
9
 
8
10
  include Celluloid
11
+ include Utils::Logging
9
12
 
10
13
  attr_reader :name
11
14
 
@@ -40,21 +43,5 @@ module Carnivore
40
43
  debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
41
44
  end
42
45
 
43
- # Custom logger helpers
44
-
45
- %w(debug info warn error).each do |key|
46
- define_method(key) do |string|
47
- log(key, string)
48
- end
49
- end
50
-
51
- def log(*args)
52
- if(args.empty?)
53
- Celluloid::Logger
54
- else
55
- severity, string = args
56
- Celluloid::Logger.send(severity.to_sym, "#{self}: #{string}")
57
- end
58
- end
59
46
  end
60
47
  end
@@ -0,0 +1,22 @@
1
+ module Carnivore
2
+ class Message
3
+
4
+ attr_reader :args
5
+
6
+ def initialize(args={})
7
+ @args = args
8
+ end
9
+
10
+ def [](k)
11
+ @args[k.to_sym] || @args[k.to_s]
12
+ end
13
+
14
+ def inspect
15
+ "<Carnivore::Message[#{self.object_id}] @args=#{args}>"
16
+ end
17
+
18
+ def to_s
19
+ "<Carnivore::Message:#{self.object_id}>"
20
+ end
21
+ end
22
+ end
@@ -15,7 +15,8 @@ module Carnivore
15
15
  def default_args(args)
16
16
  {
17
17
  :bind => '0.0.0.0',
18
- :port => '3000'
18
+ :port => '3000',
19
+ :auto_respond => true
19
20
  }.merge(args)
20
21
  end
21
22
 
@@ -23,13 +24,13 @@ module Carnivore
23
24
  srv = Reel::Server.supervise(args[:bind], args[:port]) do |con|
24
25
  while(req = con.request)
25
26
  begin
26
- msg = format(:request => req, :body => req.body)
27
+ msg = format(:request => req, :body => req.body, :connection => con)
27
28
  callbacks.each do |name|
28
29
  c_name = callback_name(name)
29
30
  debug "Dispatching message<#{msg[:message].object_id}> to callback<#{name} (#{c_name})>"
30
31
  Celluloid::Actor[c_name].async.call(msg)
31
32
  end
32
- con.respond(:ok, 'So long, and thanks for all the fish!')
33
+ con.respond(:ok, 'So long, and thanks for all the fish!') if args[:auto_respond]
33
34
  rescue => e
34
35
  con.respond(:bad_request, 'Failed to process request')
35
36
  end
@@ -12,13 +12,29 @@ module Carnivore
12
12
  def setup(args={})
13
13
  @fog = nil
14
14
  @connection_args = args[:fog]
15
- @queues = Array(args[:queues]).compact.flatten
16
- @queues.map! do |q|
17
- q.include?('.com') ? q : "/#{q.split(':')[-2,2].join('/')}"
15
+ case args[:queues]
16
+ when Hash
17
+ @queues = args[:queues]
18
+ else
19
+ @queues = Array(args[:queues]).flatten.compact
20
+ @queues = Hash[*(
21
+ @queues.size.times.map(&:to_i).zip(@queues).flatten
22
+ )]
23
+ end
24
+ @queues.values.map do |q|
25
+ q.replace(format_queue(q))
26
+ end
27
+ if(args[:processable_queues])
28
+ @processable_queues = Array(args[:processable_queues]).flatten.compact
18
29
  end
19
30
  @pause_time = args[:pause] || 5
20
31
  @receive_timeout = after(args[:receive_timeout] || 30){ terminate }
21
32
  debug "Creating SQS source instance <#{name}>"
33
+ debug "Handled queues: #{@queues.inspect}"
34
+ end
35
+
36
+ def format_queue(q)
37
+ q.include?('.com') ? q : "/#{q.split(':')[-2,2].join('/')}"
22
38
  end
23
39
 
24
40
  def connect
@@ -31,8 +47,11 @@ module Carnivore
31
47
  while(msgs.empty?)
32
48
  msgs = []
33
49
  @receive_timeout.reset
34
- msgs = @queues.map do |q|
35
- @fog.receive_message(q, 'MaxNumberOfMessages' => n).body['Message']
50
+ msgs = queues.map do |q|
51
+ m = @fog.receive_message(q, 'MaxNumberOfMessages' => n).body['Message']
52
+ m.map! do |msg|
53
+ msg.merge('SourceQueue' => q)
54
+ end
36
55
  end.flatten.compact
37
56
  @receive_timeout.reset
38
57
  if(msgs.empty?)
@@ -42,22 +61,43 @@ module Carnivore
42
61
  debug "Source<#{name}> last message repeated #{count} times"
43
62
  end
44
63
  sleep(pause_time)
64
+ else
65
+ debug "Received: #{msgs.inspect}"
45
66
  end
46
67
  count += 1
47
68
  end
48
69
  msgs.map{|m| pre_process(m) }
49
70
  end
50
71
 
51
- def send(message)
52
- @fog.send_message(@queue, message)
72
+ def transmit(message, dest=nil)
73
+ case dest
74
+ when Numeric
75
+ queue = @queues[dest]
76
+ when String, Symbol
77
+ queue = @queues[dest.to_s] || @queues.detect{|q| q.include?(dest.to_s)}
78
+ else
79
+ queue = @queues.first
80
+ end
81
+ @fog.send_message(queue, message)
53
82
  end
54
83
 
55
84
  def confirm(message)
56
- @fog.delete_message(@queue, message['ReceiptHandle'])
85
+ debug "Source<#{name}> Confirming message<#{message.object_id}>"
86
+ @fog.delete_message(message['SourceQueue'], message['ReceiptHandle'])
57
87
  end
58
88
 
59
89
  private
60
90
 
91
+ def queues
92
+ if(@processable_queues)
93
+ @queues.map do |k,v|
94
+ v if @processable_queues.include?(k)
95
+ end.compact
96
+ else
97
+ @queues.values
98
+ end
99
+ end
100
+
61
101
  def fog
62
102
  unless(@fog)
63
103
  connect
@@ -1,4 +1,6 @@
1
+ require 'carnivore/utils'
1
2
  require 'carnivore/callback'
3
+ require 'carnivore/message'
2
4
 
3
5
  module Carnivore
4
6
  class Source < Celluloid::SupervisionGroup
@@ -48,16 +50,18 @@ module Carnivore
48
50
  end
49
51
 
50
52
  include Celluloid
51
- include Celluloid::Logger
53
+ include Utils::Logging
52
54
 
53
55
  attr_reader :name
54
56
  attr_reader :callbacks
55
57
  attr_reader :auto_confirm
58
+ attr_reader :auto_process
56
59
  attr_reader :callback_supervisor
57
60
 
58
61
  def initialize(args={})
59
62
  @callbacks = []
60
63
  @callback_names = {}
64
+ @auto_process = true
61
65
  @callback_supervisor = Celluloid::SupervisionGroup.run!
62
66
  @name = args[:name] || Celluloid.uuid
63
67
  @auto_confirm = !!args[:auto_confirm]
@@ -68,7 +72,7 @@ module Carnivore
68
72
  end
69
73
  setup(args)
70
74
  connect
71
- async.process
75
+ async.process if @auto_process
72
76
  rescue => e
73
77
  debug "Failed to initialize: #{self} - #{e.class}: #{e}\n#{e.backtrace.join("\n")}"
74
78
  raise
@@ -82,12 +86,16 @@ module Carnivore
82
86
  "<#{self.class.name}:#{object_id} @name=#{name} @callbacks=#{Hash[*callbacks.map{|k,v| [k,v.object_id]}.flatten]}>"
83
87
  end
84
88
 
89
+ def to_s
90
+ "<#{self.class.name}:#{object_id} @name=#{name}>"
91
+ end
92
+
85
93
  def setup(args={})
86
- debug "<#{self.class}> No custom setup declared"
94
+ debug 'No custom setup declared'
87
95
  end
88
96
 
89
97
  def connect(args={})
90
- debug "<#{self.class}> No custom connect declared"
98
+ debug 'No custom connect declared'
91
99
  end
92
100
 
93
101
  def receive(n=1)
@@ -106,9 +114,16 @@ module Carnivore
106
114
 
107
115
  def add_callback(name, block_or_class)
108
116
  if(block_or_class.is_a?(Class))
109
- debug "Adding callback class (#{block_or_class}) under supervision. Name: #{callback_name(name)}"
110
117
  size = block_or_class.workers || 1
111
- @callback_supervisor.pool block_or_class, as: callback_name(name), size: size, args: [name]
118
+ if(size < 1)
119
+ warn "Callback class (#{block_or_class}) defined no workers. Skipping."
120
+ elsif(size == 1)
121
+ debug "Adding callback class (#{block_or_class}) under supervision. Name: #{callback_name(name)}"
122
+ @callback_supervisor.supervise_as callback_name(name), block_or_class, name
123
+ else
124
+ debug "Adding callback class (#{block_or_class}) under supervision pool (#{size} workers). Name: #{callback_name(name)}"
125
+ @callback_supervisor.pool block_or_class, as: callback_name(name), size: size, args: [name]
126
+ end
112
127
  else
113
128
  debug "Adding custom callback class from block (#{block_or_class}) under supervision. Name: #{callback_name(name)}"
114
129
  @callback_supervisor.supervise_as callback_name(name), Callback, name, block_or_class
@@ -134,7 +149,10 @@ module Carnivore
134
149
  end
135
150
 
136
151
  def format(msg)
137
- {:message => msg, :source => self}
152
+ Message.new(
153
+ :message => msg,
154
+ :source => self
155
+ )
138
156
  end
139
157
 
140
158
  def process
@@ -2,7 +2,11 @@ module Carnivore
2
2
  class Supervisor < Celluloid::SupervisionGroup
3
3
 
4
4
  Source.sources.each do |source|
5
- supervise source.klass, as: source.source_hash[:name], args: [source.source_hash]
5
+ supervise(
6
+ source.klass,
7
+ as: source.source_hash[:name],
8
+ args: [source.source_hash]
9
+ )
6
10
  end
7
11
 
8
12
  end
@@ -9,10 +9,28 @@ module Carnivore
9
9
  k.gsub(/(?<![A-Z])([A-Z])/, '_\1').sub(/^_/, '').downcase.to_sym,
10
10
  v.is_a?(Hash) ? symbolize_hash(v) : v
11
11
  ]
12
- end.flatten
12
+ end.flatten(1)
13
13
  )]
14
14
  end
15
15
  end
16
16
 
17
+ module Logging
18
+
19
+ %w(debug info warn error).each do |key|
20
+ define_method(key) do |string|
21
+ log(key, string)
22
+ end
23
+ end
24
+
25
+ def log(*args)
26
+ if(args.empty?)
27
+ Celluloid::Logger
28
+ else
29
+ severity, string = args
30
+ Celluloid::Logger.send(severity.to_sym, "#{self}: #{string}")
31
+ end
32
+ end
33
+
34
+ end
17
35
  end
18
36
  end
@@ -1,5 +1,5 @@
1
1
  module Carnivore
2
2
  class Version < Gem::Version
3
3
  end
4
- VERSION = Version.new('0.1.2')
4
+ VERSION = Version.new('0.1.4')
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carnivore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-13 00:00:00.000000000 Z
12
+ date: 2013-09-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -107,6 +107,7 @@ files:
107
107
  - lib/carnivore/version.rb
108
108
  - lib/carnivore/runner.rb
109
109
  - lib/carnivore/config.rb
110
+ - lib/carnivore/message.rb
110
111
  - lib/carnivore/utils.rb
111
112
  - lib/carnivore/container.rb
112
113
  - lib/carnivore.rb