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 +8 -0
- data/lib/carnivore/callback.rb +3 -16
- data/lib/carnivore/message.rb +22 -0
- data/lib/carnivore/source/http.rb +4 -3
- data/lib/carnivore/source/sqs.rb +48 -8
- data/lib/carnivore/source.rb +25 -7
- data/lib/carnivore/supervisor.rb +5 -1
- data/lib/carnivore/utils.rb +19 -1
- data/lib/carnivore/version.rb +1 -1
- metadata +3 -2
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
|
|
data/lib/carnivore/callback.rb
CHANGED
@@ -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
|
data/lib/carnivore/source/sqs.rb
CHANGED
@@ -12,13 +12,29 @@ module Carnivore
|
|
12
12
|
def setup(args={})
|
13
13
|
@fog = nil
|
14
14
|
@connection_args = args[:fog]
|
15
|
-
|
16
|
-
|
17
|
-
|
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 =
|
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
|
52
|
-
|
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
|
-
|
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
|
data/lib/carnivore/source.rb
CHANGED
@@ -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
|
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
|
94
|
+
debug 'No custom setup declared'
|
87
95
|
end
|
88
96
|
|
89
97
|
def connect(args={})
|
90
|
-
debug
|
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
|
-
|
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
|
-
|
152
|
+
Message.new(
|
153
|
+
:message => msg,
|
154
|
+
:source => self
|
155
|
+
)
|
138
156
|
end
|
139
157
|
|
140
158
|
def process
|
data/lib/carnivore/supervisor.rb
CHANGED
@@ -2,7 +2,11 @@ module Carnivore
|
|
2
2
|
class Supervisor < Celluloid::SupervisionGroup
|
3
3
|
|
4
4
|
Source.sources.each do |source|
|
5
|
-
supervise
|
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
|
data/lib/carnivore/utils.rb
CHANGED
@@ -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
|
data/lib/carnivore/version.rb
CHANGED
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.
|
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-
|
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
|