pheme 0.0.3 → 0.0.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.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/circle.yml +7 -3
- data/lib/pheme.rb +2 -0
- data/lib/pheme/configuration.rb +1 -1
- data/lib/pheme/queue_poller.rb +31 -5
- data/lib/pheme/rollbar.rb +6 -0
- data/lib/pheme/version.rb +1 -1
- data/pheme.gemspec +2 -1
- data/spec/queue_poller_spec.rb +60 -0
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25cd1b421feda98de4c2a6e14505c6f6c73f86e8
|
4
|
+
data.tar.gz: a90b834b7f9daf20e4cc371c9d7c36ffeb71a703
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d2101348a395491f6df3dbc74e14ab7e2701f21566f876d0a0f9fe256128a592b75280f18094f24ee97f90a420d5c0a7d9b1fc0c1ff0c2d294c9ee6d69d7bf6
|
7
|
+
data.tar.gz: 4f4e17a4660e095ca04115d600a257406f5e91f56695dc93bccf3d59ab85df2071b6dcc0d0607a7adc466f83f150d2f19e3ba8cfd55857f952f79a0fc6cb283e
|
data/Gemfile
CHANGED
data/circle.yml
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
machine:
|
2
|
+
ruby:
|
3
|
+
version: 2.2.2
|
1
4
|
dependencies:
|
2
5
|
override:
|
3
|
-
- 'rvm-exec 2.
|
6
|
+
- 'rvm-exec 2.2.2 bundle install'
|
4
7
|
- 'rvm-exec 2.3.0 bundle install'
|
5
|
-
|
8
|
+
post:
|
9
|
+
- bundle exec bundle-audit update && bundle exec bundle-audit check
|
6
10
|
test:
|
7
11
|
override:
|
8
|
-
- 'rvm-exec 2.
|
12
|
+
- 'rvm-exec 2.2.2 bundle exec rspec'
|
9
13
|
- 'rvm-exec 2.3.0 bundle exec rspec'
|
data/lib/pheme.rb
CHANGED
@@ -2,10 +2,12 @@ require 'active_support/all'
|
|
2
2
|
require 'recursive-open-struct'
|
3
3
|
require 'aws-sdk'
|
4
4
|
require 'securerandom'
|
5
|
+
require 'smarter_csv'
|
5
6
|
|
6
7
|
require 'pheme/version'
|
7
8
|
require 'pheme/configuration'
|
8
9
|
require 'pheme/logger'
|
10
|
+
require 'pheme/rollbar'
|
9
11
|
require 'pheme/topic_publisher'
|
10
12
|
require 'pheme/message_handler'
|
11
13
|
require 'pheme/queue_poller'
|
data/lib/pheme/configuration.rb
CHANGED
data/lib/pheme/queue_poller.rb
CHANGED
@@ -1,29 +1,39 @@
|
|
1
1
|
module Pheme
|
2
2
|
class QueuePoller
|
3
|
-
attr_accessor :queue_url, :queue_poller, :connection_pool_block, :poller_configuration
|
3
|
+
attr_accessor :queue_url, :queue_poller, :connection_pool_block, :format, :max_messages, :poller_configuration
|
4
4
|
|
5
|
-
def initialize(queue_url:, connection_pool_block: false, poller_configuration: {})
|
5
|
+
def initialize(queue_url:, connection_pool_block: false, max_messages: nil, format: :json, poller_configuration: {})
|
6
6
|
raise ArgumentError, "must specify non-nil queue_url" unless queue_url.present?
|
7
7
|
@queue_url = queue_url
|
8
8
|
@queue_poller = Aws::SQS::QueuePoller.new(queue_url)
|
9
9
|
@connection_pool_block = connection_pool_block
|
10
|
+
@format = format
|
11
|
+
@max_messages = max_messages
|
10
12
|
@poller_configuration = {
|
11
13
|
wait_time_seconds: 10, # amount of time a long polling receive call can wait for a mesage before receiving a empty response (which will trigger another polling request)
|
12
14
|
idle_timeout: 20, # disconnects poller after 20 seconds of idle time
|
13
15
|
skip_delete: true, # manually delete messages
|
14
16
|
}.merge(poller_configuration || {})
|
17
|
+
|
18
|
+
if max_messages
|
19
|
+
queue_poller.before_request do |stats|
|
20
|
+
throw :stop_polling if stats.received_message_count >= max_messages
|
21
|
+
end
|
22
|
+
end
|
15
23
|
end
|
16
24
|
|
17
25
|
def poll
|
18
26
|
Pheme.log(:info, "Long-polling for messages on #{queue_url}")
|
19
27
|
with_optional_connection_pool_block do
|
20
28
|
queue_poller.poll(poller_configuration) do |message|
|
29
|
+
data = parse_message(message)
|
21
30
|
begin
|
22
|
-
handle(
|
31
|
+
handle(data)
|
23
32
|
queue_poller.delete_message(message)
|
24
33
|
rescue => e
|
25
34
|
Pheme.log(:error, "Exception: #{e.inspect}")
|
26
35
|
Pheme.log(:error, e.backtrace.join("\n"))
|
36
|
+
Pheme.rollbar(e, "#{self.class} failed to process message", data)
|
27
37
|
end
|
28
38
|
end
|
29
39
|
end
|
@@ -33,8 +43,24 @@ module Pheme
|
|
33
43
|
def parse_message(message)
|
34
44
|
Pheme.log(:info, "Received JSON payload: #{message.body}")
|
35
45
|
body = JSON.parse(message.body)
|
36
|
-
|
37
|
-
|
46
|
+
case format
|
47
|
+
when :csv
|
48
|
+
parse_csv(body['Message'])
|
49
|
+
when :json
|
50
|
+
parse_json(body['Message'])
|
51
|
+
else
|
52
|
+
raise ArgumentError.new("Unknown format #{format}. Valid formats: :csv, :json.")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_csv(message_contents)
|
57
|
+
parsed_body = SmarterCSV.process(StringIO.new(message_contents))
|
58
|
+
parsed_body.map{ |item| RecursiveOpenStruct.new(item, recurse_over_arrays: true) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def parse_json(message_contents)
|
62
|
+
parsed_body = JSON.parse(message_contents)
|
63
|
+
RecursiveOpenStruct.new({wrapper: parsed_body}, recurse_over_arrays: true).wrapper
|
38
64
|
end
|
39
65
|
|
40
66
|
def handle(message)
|
data/lib/pheme/version.rb
CHANGED
data/pheme.gemspec
CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.required_ruby_version = ">= 2.1.0"
|
22
22
|
|
23
23
|
gem.add_dependency "aws-sdk", "~> 2"
|
24
|
-
gem.add_dependency "activesupport", "
|
24
|
+
gem.add_dependency "activesupport", ">= 4"
|
25
25
|
gem.add_dependency "recursive-open-struct", "~> 1"
|
26
|
+
gem.add_dependency "smarter_csv", "~> 1"
|
26
27
|
|
27
28
|
gem.add_development_dependency "rspec", "~> 3.4"
|
28
29
|
gem.add_development_dependency "rspec_junit_formatter", "~> 0.2"
|
data/spec/queue_poller_spec.rb
CHANGED
@@ -3,6 +3,8 @@ describe Pheme::QueuePoller do
|
|
3
3
|
let(:poller) do
|
4
4
|
poller = double
|
5
5
|
allow(poller).to receive(:poll).with(kind_of(Hash))
|
6
|
+
allow(poller).to receive(:parse_message)
|
7
|
+
allow(poller).to receive(:before_request)
|
6
8
|
poller
|
7
9
|
end
|
8
10
|
before(:each) do
|
@@ -22,6 +24,64 @@ describe Pheme::QueuePoller do
|
|
22
24
|
expect { ExampleQueuePoller.new(queue_url: nil) }.to raise_error(ArgumentError)
|
23
25
|
end
|
24
26
|
end
|
27
|
+
|
28
|
+
context "when initialized with max_messages" do
|
29
|
+
it "should set max_messages" do
|
30
|
+
expect(ExampleQueuePoller.new(queue_url: "queue_url", max_messages: 5).max_messages).to eq(5)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#parse_message" do
|
36
|
+
context "with JSON message" do
|
37
|
+
subject { ExampleQueuePoller.new(queue_url: queue_url) }
|
38
|
+
|
39
|
+
let!(:message) { OpenStruct.new({
|
40
|
+
body: '{"Message":"{\"test\":\"test\"}"}'
|
41
|
+
})}
|
42
|
+
|
43
|
+
it 'should parse the message correctly' do
|
44
|
+
expect(subject.parse_message(message).test).to eq("test")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with CSV message" do
|
49
|
+
subject { ExampleQueuePoller.new(queue_url: queue_url, format: :csv) }
|
50
|
+
|
51
|
+
let!(:message) { OpenStruct.new({
|
52
|
+
body:'{"Message":"test,test2\nvalue,value2\nvalue3,value4"}'
|
53
|
+
})}
|
54
|
+
|
55
|
+
it 'should parse the message correctly' do
|
56
|
+
expect(subject.parse_message(message)).to be_a(Array)
|
57
|
+
expect(subject.parse_message(message).count).to eq(2)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "with unknown message format" do
|
62
|
+
subject { ExampleQueuePoller.new(queue_url: queue_url, format: :invalid_format) }
|
63
|
+
|
64
|
+
let!(:message) { OpenStruct.new({
|
65
|
+
body:'{"Message":"test,test2\nvalue,value2\nvalue3,value4"}'
|
66
|
+
})}
|
67
|
+
|
68
|
+
it 'should raise an error' do
|
69
|
+
expect{ subject.parse_message(message) }.to raise_error
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with array JSON message" do
|
74
|
+
subject { ExampleQueuePoller.new(queue_url: queue_url).parse_message(message) }
|
75
|
+
let!(:message) { OpenStruct.new({
|
76
|
+
body: '{"Message":"[[{\"test\":\"test\"}]]"}'
|
77
|
+
})}
|
78
|
+
it 'should parse the message correctly' do
|
79
|
+
expect(subject.first.first.test).to eq("test")
|
80
|
+
expect(subject).to be_a Array
|
81
|
+
expect(subject.first).to be_a Array
|
82
|
+
expect(subject.first.first).to be_a RecursiveOpenStruct
|
83
|
+
end
|
84
|
+
end
|
25
85
|
end
|
26
86
|
|
27
87
|
describe "#poll" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pheme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Graham
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '4'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '4'
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: smarter_csv
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,6 +112,7 @@ files:
|
|
98
112
|
- lib/pheme/logger.rb
|
99
113
|
- lib/pheme/message_handler.rb
|
100
114
|
- lib/pheme/queue_poller.rb
|
115
|
+
- lib/pheme/rollbar.rb
|
101
116
|
- lib/pheme/topic_publisher.rb
|
102
117
|
- lib/pheme/version.rb
|
103
118
|
- pheme.gemspec
|
@@ -144,4 +159,3 @@ test_files:
|
|
144
159
|
- spec/support/example_queue_poller.rb
|
145
160
|
- spec/topic_publisher_spec.rb
|
146
161
|
- spec/version_spec.rb
|
147
|
-
has_rdoc:
|