pheme 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46433ad750c6060d267dc7124847580d107274c9
4
- data.tar.gz: 11cf1262b1da8a5e590eef8ef023a88734f1874f
3
+ metadata.gz: 25cd1b421feda98de4c2a6e14505c6f6c73f86e8
4
+ data.tar.gz: a90b834b7f9daf20e4cc371c9d7c36ffeb71a703
5
5
  SHA512:
6
- metadata.gz: b309d7c66b7ed47901c4748476e5ac428513dfb89b531c64f1936f0f48e1dfc555acc3fbc586372c25592015d9998f6e6bfd6c236a21d8504bc26e11afa8b919
7
- data.tar.gz: f9c7870ba06f05d0d01dbc35f09e6d392cb5d4ebd272d0ef7fc7ef938516d52862517875322aafe03390441d02829148160f7ddc8315b7136f5924cfcfe742c9
6
+ metadata.gz: 8d2101348a395491f6df3dbc74e14ab7e2701f21566f876d0a0f9fe256128a592b75280f18094f24ee97f90a420d5c0a7d9b1fc0c1ff0c2d294c9ee6d69d7bf6
7
+ data.tar.gz: 4f4e17a4660e095ca04115d600a257406f5e91f56695dc93bccf3d59ab85df2071b6dcc0d0607a7adc466f83f150d2f19e3ba8cfd55857f952f79a0fc6cb283e
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
+ group :development, :test do
4
+ gem 'bundler-audit', require: false
5
+ end
6
+
3
7
  gemspec
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.1.0 bundle install'
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.1.0 bundle exec rspec'
12
+ - 'rvm-exec 2.2.2 bundle exec rspec'
9
13
  - 'rvm-exec 2.3.0 bundle exec rspec'
@@ -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'
@@ -16,7 +16,7 @@ module Pheme
16
16
  end
17
17
 
18
18
  class Configuration
19
- ATTRIBUTES = [:sns_client, :sqs_client, :logger]
19
+ ATTRIBUTES = [:sns_client, :sqs_client, :logger, :rollbar]
20
20
  attr_accessor *ATTRIBUTES
21
21
 
22
22
  def initialize
@@ -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(parse_message(message))
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
- parsed_body = JSON.parse(body['Message'])
37
- RecursiveOpenStruct.new(parsed_body, recurse_over_arrays: true)
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)
@@ -0,0 +1,6 @@
1
+ module Pheme
2
+ def self.rollbar(exception, message, data={})
3
+ return if configuration.rollbar.nil?
4
+ configuration.rollbar.error(exception, message, data)
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Pheme
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -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", "~> 4"
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"
@@ -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.3
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-09-02 00:00:00.000000000 Z
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: