queued-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 865c893471a8fd7a247099588c38c287536d5e19
4
+ data.tar.gz: 2abff73f13ff6a6ac44a180fb34273f4b76cfb3f
5
+ SHA512:
6
+ metadata.gz: f41cc90de1bf6cf45a2900aaf40cedcf3ceca0ec86795b2de8eb53e2c0b8c97f0f5b222f1777d3f8977d94d675dfb0bded03408bc9647c3865dc3c81e8252547
7
+ data.tar.gz: 091ab0abc75cb0f7c5f6972098f92a0a1d16c6a2aa13f10f90fb2e93ec59b053bea129134d6a7947a97a704bff6191d945834b97fed6db4287aa01f81e33490c
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'http://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ queue (0.0.1)
5
+ faraday (>= 0.8, < 0.10)
6
+ faraday_middleware (>= 0.8, < 0.10)
7
+ multi_json (~> 1.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ addressable (2.3.5)
13
+ crack (0.4.1)
14
+ safe_yaml (~> 0.9.0)
15
+ diff-lcs (1.2.4)
16
+ faraday (0.8.8)
17
+ multipart-post (~> 1.2.0)
18
+ faraday_middleware (0.9.0)
19
+ faraday (>= 0.7.4, < 0.9)
20
+ multi_json (1.8.0)
21
+ multipart-post (1.2.0)
22
+ rake (10.1.0)
23
+ rspec (2.14.1)
24
+ rspec-core (~> 2.14.0)
25
+ rspec-expectations (~> 2.14.0)
26
+ rspec-mocks (~> 2.14.0)
27
+ rspec-core (2.14.5)
28
+ rspec-expectations (2.14.3)
29
+ diff-lcs (>= 1.1.3, < 2.0)
30
+ rspec-mocks (2.14.3)
31
+ safe_yaml (0.9.7)
32
+ webmock (1.13.0)
33
+ addressable (>= 2.2.7)
34
+ crack (>= 0.3.2)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ queue!
41
+ rake
42
+ rspec
43
+ webmock
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Scott Nelson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ queued-ruby
2
+ ===
3
+
4
+ [Queued](http://github.com/scttnlsn/queued) client for Ruby
5
+
6
+ Example
7
+ ---
8
+
9
+ ```ruby
10
+ require 'queued-ruby'
11
+
12
+ client = Queued::Client.new('http://localhost:5353', auth: 'secret')
13
+ queue = client.queue('testing')
14
+ ```
15
+
16
+ Producer:
17
+
18
+ ```ruby
19
+ item = queue.enqueue(foo: 'bar')
20
+ ```
21
+
22
+ Consumer:
23
+
24
+ ```ruby
25
+ item = queue.dequeue(timeout: 10, wait: 30)
26
+ if item
27
+ p item.value
28
+ item.complete
29
+ end
30
+ ```
31
+
32
+ Install
33
+ ---
34
+
35
+ gem install queued-ruby
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec) do |spec|
4
+ spec.pattern = 'spec/**/*_spec.rb'
5
+ end
6
+
7
+ task :default => :spec
@@ -0,0 +1,34 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Queued
5
+ class Client
6
+ def initialize(url, options = {})
7
+ @url = url
8
+ @auth = options[:auth]
9
+
10
+ @conn = Faraday.new(:url => @url) do |conn|
11
+ conn.use Middleware::Errors
12
+
13
+ conn.request :json
14
+ conn.response :json, :content_type => /\bjson$/
15
+
16
+ conn.adapter Faraday.default_adapter
17
+ end
18
+
19
+ if @auth
20
+ @conn.basic_auth('', @auth)
21
+ end
22
+ end
23
+
24
+ def queue(name)
25
+ Queue.new(self, name)
26
+ end
27
+
28
+ [:get, :post, :put, :delete].each do |method|
29
+ define_method method do |*args, &block|
30
+ @conn.send(method, *args, &block)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Queued
2
+ class Item
3
+ attr_reader :value, :type, :url
4
+
5
+ def initialize(client, options = {})
6
+ @client = client
7
+ @value = options[:value]
8
+ @type = options[:type]
9
+ @url = options[:url]
10
+ end
11
+
12
+ def complete
13
+ @client.delete @url
14
+ self
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ module Queued
2
+ class Error < StandardError; end
3
+ class BadRequest < Error; end
4
+ class Unauthorized < Error; end
5
+ class InternalServerError < Error; end
6
+
7
+ module Middleware
8
+ ERROR_MAP = {
9
+ 400 => BadRequest,
10
+ 401 => Unauthorized,
11
+ 500 => InternalServerError
12
+ }
13
+
14
+ class Errors < Faraday::Response::Middleware
15
+ def on_complete(env)
16
+ return unless error = ERROR_MAP[env[:status]]
17
+ raise error, error_message(env[:body])
18
+ end
19
+
20
+ private
21
+
22
+ def error_message(body)
23
+ if body && body.is_a?(Hash)
24
+ body['error']
25
+ else
26
+ body
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ module Queued
2
+ module Middleware
3
+ autoload :Errors, 'queued/middleware/errors'
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ module Queued
2
+ class Queue
3
+ def initialize(client, name)
4
+ @client = client
5
+ @name = name
6
+ end
7
+
8
+ def enqueue(value, type = 'text/plain')
9
+ res = @client.post do |req|
10
+ req.url "/#{@name}"
11
+ req.headers['Content-Type'] = type
12
+ req.body = value
13
+ end
14
+
15
+ Item.new(@client,
16
+ value: value,
17
+ type: type,
18
+ url: res.headers['Location'])
19
+ end
20
+
21
+ def dequeue(params = {})
22
+ res = @client.post do |req|
23
+ req.url "/#{@name}/dequeue"
24
+ req.params[:wait] = params[:wait] if params[:wait]
25
+ req.params[:timeout] = params[:timeout] if params[:timeout]
26
+ end
27
+
28
+ return nil if res.status === 404
29
+
30
+ Item.new(@client,
31
+ value: res.body,
32
+ type: res.headers['Content-Type'],
33
+ url: res.headers['Location'])
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Queued
2
+ VERSION = '0.1.0'
3
+ end
data/lib/queued.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Queued
2
+ autoload :Client, 'queued/client'
3
+ autoload :Item, 'queued/item'
4
+ autoload :Queue, 'queued/queue'
5
+ autoload :Middleware, 'queued/middleware'
6
+ end
@@ -0,0 +1,24 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ require 'queued/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'queued-ruby'
7
+ spec.version = Queued::VERSION
8
+ spec.files = Dir.glob('**/*')
9
+ spec.require_paths = ['lib']
10
+ spec.summary = 'Queued client library'
11
+ spec.description = 'Queued client library for Ruby'
12
+ spec.authors = ['Scott Nelson']
13
+ spec.email = 'scott@scttnlsn.com'
14
+ spec.homepage = 'https://github.com/scttnlsn/queued-rb'
15
+
16
+ spec.add_dependency 'faraday', ['>= 0.8', '< 0.10']
17
+ spec.add_dependency 'faraday_middleware', ['>= 0.8', '< 0.10']
18
+ spec.add_dependency 'multi_json', ['~> 1.0']
19
+ spec.add_dependency 'json', ['~> 1.7'] if RUBY_VERSION < '1.9'
20
+
21
+ spec.add_development_dependency('rake')
22
+ spec.add_development_dependency('rspec')
23
+ spec.add_development_dependency('webmock')
24
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe Queued::Client do
4
+ let!(:client) { Queued::Client.new('http://example.com') }
5
+
6
+ it 'raises errors' do
7
+ stub_request(:get, 'http://example.com/foo').to_return(
8
+ status: 500,
9
+ headers: { 'Content-Type' => 'application/json' },
10
+ body: '{"error": "Something went wrong"}')
11
+
12
+ expect { client.get '/foo' }.to raise_error(Queued::InternalServerError)
13
+ end
14
+
15
+ it 'sends auth info' do
16
+ stub_request(:get, 'http://:testing@example.com/foo')
17
+
18
+ client = Queued::Client.new('http://example.com', auth: 'testing')
19
+ client.get '/foo'
20
+
21
+ assert_requested :get, 'http://:testing@example.com/foo', times: 1
22
+ end
23
+
24
+ describe '#queue' do
25
+ it 'should return queue' do
26
+ expect(client.queue(:foo)).to be_a(Queued::Queue)
27
+ end
28
+ end
29
+ end
data/spec/item_spec.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Queued::Item do
4
+ let!(:client) { Queued::Client.new('http://example.com') }
5
+ let!(:item) { Queued::Item.new(client, url: 'http://example.com/foo/1') }
6
+
7
+ describe '#complete' do
8
+ before :each do
9
+ stub_request(:delete, 'http://example.com/foo/1')
10
+ end
11
+
12
+ it 'deletes to complete endpoint' do
13
+ item.complete()
14
+ assert_requested :delete, 'http://example.com/foo/1', times: 1
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe Queued::Queue do
4
+ let!(:client) { Queued::Client.new('http://example.com') }
5
+ let!(:queue) { Queued::Queue.new(client, 'foo') }
6
+
7
+ describe '#enqueue' do
8
+ before :each do
9
+ stub_request(:post, 'http://example.com/foo').
10
+ to_return(headers: { 'Location' => 'http://example.com/foo/1' })
11
+ end
12
+
13
+ it 'posts to enqueue endpoint' do
14
+ queue.enqueue('bar')
15
+
16
+ assert_requested :post, 'http://example.com/foo',
17
+ headers: { 'Content-Type' => 'text/plain' },
18
+ body: 'bar',
19
+ times: 1
20
+ end
21
+
22
+ it 'returns enqueued item' do
23
+ item = queue.enqueue('bar')
24
+
25
+ expect(item).to be_a(Queued::Item)
26
+ expect(item.value).to eq 'bar'
27
+ expect(item.type).to eq 'text/plain'
28
+ expect(item.url).to eq 'http://example.com/foo/1'
29
+ end
30
+
31
+ it 'encodes JSON values' do
32
+ queue.enqueue({ bar: 'baz' }, 'application/json')
33
+
34
+ assert_requested :post, 'http://example.com/foo',
35
+ headers: { 'Content-Type' => 'application/json' },
36
+ body: '{"bar":"baz"}',
37
+ times: 1
38
+ end
39
+ end
40
+
41
+ describe '#dequeue' do
42
+ it 'posts to dequeue endpoint' do
43
+ stub_request(:post, 'http://example.com/foo/dequeue?timeout=2&wait=1').to_return(
44
+ headers: { 'Content-Type' => 'text/plain', 'Location' => 'http://example.com/foo/1' },
45
+ body: 'bar')
46
+
47
+ queue.dequeue(wait: 1, timeout: 2)
48
+ assert_requested :post, 'http://example.com/foo/dequeue?timeout=2&wait=1', times: 1
49
+ end
50
+
51
+ it 'returns dequeued item' do
52
+ stub_request(:post, 'http://example.com/foo/dequeue').to_return(
53
+ headers: { 'Content-Type' => 'text/plain', 'Location' => 'http://example.com/foo/1' },
54
+ body: 'bar')
55
+
56
+ item = queue.dequeue()
57
+
58
+ expect(item).to be_a(Queued::Item)
59
+ expect(item.value).to eq 'bar'
60
+ expect(item.type).to eq 'text/plain'
61
+ expect(item.url).to eq 'http://example.com/foo/1'
62
+ end
63
+
64
+ it 'returns nil on 404' do
65
+ stub_request(:post, 'http://example.com/foo/dequeue').to_return(status: 404)
66
+
67
+ item = queue.dequeue()
68
+
69
+ expect(item).to be_nil
70
+ end
71
+
72
+ it 'parses JSON responses' do
73
+ stub_request(:post, 'http://example.com/foo/dequeue').to_return(
74
+ headers: { 'Content-Type' => 'application/json', 'Location' => 'http://example.com/foo/1' },
75
+ body: '{"bar":"baz"}')
76
+
77
+ item = queue.dequeue()
78
+
79
+ expect(item).to be_a(Queued::Item)
80
+ expect(item.type).to eq 'application/json'
81
+ expect(item.value).to eq 'bar' => 'baz'
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'queued'
4
+ require 'webmock/rspec'
5
+
6
+ WebMock.disable_net_connect!
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: queued-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Scott Nelson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: '0.10'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0.8'
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: '0.10'
33
+ - !ruby/object:Gem::Dependency
34
+ name: faraday_middleware
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0.8'
40
+ - - <
41
+ - !ruby/object:Gem::Version
42
+ version: '0.10'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0.8'
50
+ - - <
51
+ - !ruby/object:Gem::Version
52
+ version: '0.10'
53
+ - !ruby/object:Gem::Dependency
54
+ name: multi_json
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ version: '1.0'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: '1.0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rake
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: webmock
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ description: Queued client library for Ruby
110
+ email: scott@scttnlsn.com
111
+ executables: []
112
+ extensions: []
113
+ extra_rdoc_files: []
114
+ files:
115
+ - Gemfile
116
+ - Gemfile.lock
117
+ - lib/queued/client.rb
118
+ - lib/queued/item.rb
119
+ - lib/queued/middleware/errors.rb
120
+ - lib/queued/middleware.rb
121
+ - lib/queued/queue.rb
122
+ - lib/queued/version.rb
123
+ - lib/queued.rb
124
+ - LICENSE
125
+ - queued-ruby.gemspec
126
+ - Rakefile
127
+ - README.md
128
+ - spec/client_spec.rb
129
+ - spec/item_spec.rb
130
+ - spec/queue_spec.rb
131
+ - spec/spec_helper.rb
132
+ homepage: https://github.com/scttnlsn/queued-rb
133
+ licenses: []
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.0.2
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Queued client library
155
+ test_files: []