carnivore 0.1.2 → 0.1.4

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/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