net-http-pool 0.0.2

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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+ gem "rake"
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Net::HTTP::Pool
2
+
3
+ ![Pool](http://www.beijingboyce.com/wp-content/uploads/2008/03/pool-table.JPG)
4
+
5
+ Act like a database pool but for HTTP.
6
+
7
+ It will attenmpt to open (default: 5) persistent connections to a given server.
8
+ Then you can make your requests as you want and the pool get recycled.
9
+ The implementation it's made throght actors (celluloid) so the behaviour in the
10
+ verb block it's async.
11
+
12
+ The target of the lib it's to provide DB-like pool to handle information
13
+ exchange.
14
+
15
+ ## Example
16
+
17
+ ```ruby
18
+ require 'net/http/pool'
19
+
20
+ pool = Net::HTTP::Pool.new("http://elcuervo.co")
21
+ pool.get("/humans.txt") do |response|
22
+ File.open('nevermore.txt', 'w') { |f| f << response.body } if response.code == "200"
23
+ end
24
+ ```
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ task :test do
2
+ require "cutest"
3
+ require "capybara/dsl"
4
+
5
+ Cutest.run(Dir["test/*.rb"])
6
+
7
+ class Cutest::Scope
8
+ include Capybara::DSL
9
+ end
10
+ end
11
+
12
+ task :default => :test
data/SPEC.md ADDED
@@ -0,0 +1,3 @@
1
+ # Pool of persistent connections
2
+
3
+ Pool of connections to use with Spirit... for now
@@ -0,0 +1,84 @@
1
+ require 'celluloid'
2
+ require 'net/http/persistent'
3
+
4
+ # Public: The Pool itself
5
+ #
6
+ # host - The string of the host.
7
+ class Net::HTTP::Pool
8
+ include Celluloid
9
+
10
+ # Private: Custom Error for a missing block in the call.
11
+ class MissingBlock < StandardError
12
+ def message
13
+ "You must pass a block"
14
+ end
15
+ end
16
+
17
+ # Public: The Connection Pool.
18
+ #
19
+ # host - The string of the host.
20
+ # options - The hash of options (default: {}).
21
+ # :size - The integer size of the pool (default: 5)
22
+ class Connections
23
+ include Celluloid
24
+
25
+ attr_reader :pool
26
+
27
+ def initialize(host, options = {})
28
+ @current_index = 0
29
+ @pool = Array.new(options.fetch(:size, 5)) do
30
+ connection = Net::HTTP::Persistent.new(host)
31
+ connection.idle_timeout = nil
32
+ connection
33
+ end
34
+ end
35
+
36
+ # Private: Round robin one of the connections
37
+ #
38
+ # &block - The block to be called passing the current connection
39
+ def round_robin(&block)
40
+ raise MissingBlock unless block
41
+ @current_index = @current_index > @pool.size ? 0 : @current_index + 1
42
+ yield @pool[@current_index] if block
43
+ end
44
+
45
+ # Public: Helper to access the connection asynchronous
46
+ #
47
+ # &block - The block to be called passing the current connection
48
+ def with(&block)
49
+ round_robin! &block
50
+ end
51
+ end
52
+
53
+ def initialize(host, options = {})
54
+ @pool = Connections.new(host, options)
55
+ @uri = URI(host)
56
+ end
57
+
58
+ def get(path, headers = {}, &block)
59
+ request!(path, Net::HTTP::Get, nil, headers, &block)
60
+ end
61
+
62
+ def post(path, body = nil, headers = {}, &block)
63
+ request!(path, Net::HTTP::Post, body, headers, &block)
64
+ end
65
+
66
+ def put(path, body = nil, headers = {}, &block)
67
+ request!(path, Net::HTTP::Put, body, headers, &block)
68
+ end
69
+
70
+ def delete(path, headers = {}, &block)
71
+ request!(path, Net::HTTP::Delete, headers, &block)
72
+ end
73
+
74
+ def request(path, type, body = nil, headers = {}, &block)
75
+ raise MissingBlock unless block
76
+ @pool.with do |connection|
77
+ request = type.new(path)
78
+ request.body = body if body
79
+ headers.each { |key, value| request.add_field(key, value) }
80
+ request['Content-Length'] = body && body.length || 0
81
+ yield connection.request(@uri, request) if block
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "net-http-pool"
3
+ s.version = "0.0.2"
4
+ s.summary = "Persistent pool of HTTP connections"
5
+ s.authors = ["elcuervo"]
6
+ s.email = ["yo@brunoaguirre.com"]
7
+ s.homepage = "http://github.com/elcuervo/net-http-pool"
8
+ s.files = `git ls-files`.split("\n")
9
+ s.test_files = `git ls-files test`.split("\n")
10
+
11
+ s.add_dependency("net-http-persistent", ">= 2.6")
12
+ s.add_dependency("celluloid", "~> 0.9.0")
13
+
14
+ s.add_development_dependency("cutest", "~> 1.1.3")
15
+ s.add_development_dependency("capybara", "~> 1.1.2")
16
+ s.add_development_dependency("mock-server", "~> 0.1.2")
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'cutest'
2
+ require_relative '../lib/net/http/pool'
3
+
4
+ scope do
5
+ test "generates the default pool" do
6
+ connections = Net::HTTP::Pool::Connections.new('http://localhost', size: 9)
7
+ assert connections.pool.size == 9
8
+ end
9
+ end
data/test/pool.rb ADDED
@@ -0,0 +1,68 @@
1
+ require 'cutest'
2
+ require 'mock_server'
3
+ require_relative '../lib/net/http/pool'
4
+
5
+ extend MockServer::Methods
6
+
7
+ mock_server {
8
+ get '/' do
9
+ 'What is up dog!'
10
+ end
11
+
12
+ get '/marco' do
13
+ 'polo'
14
+ end
15
+
16
+ post '/post' do
17
+ params[:test] ? 'this is a test' : 'the post'
18
+ end
19
+
20
+ put '/put' do
21
+ params[:run] || 'the put'
22
+ end
23
+
24
+ get '/wait' do
25
+ sleep 5
26
+ "Finally!"
27
+ end
28
+
29
+ delete('/delete') {}
30
+ }
31
+
32
+ scope do
33
+ setup do
34
+ @pool = Net::HTTP::Pool.new("http://localhost:4000/")
35
+ end
36
+
37
+ test "check that the HTTP verbs do work" do
38
+ @pool.get("/") do |res|
39
+ assert_equal "200", res.code
40
+ assert_equal 'What is up dog!', res.body
41
+ end
42
+
43
+ @pool.get("/marco") do |res|
44
+ assert_equal "200", res.code
45
+ assert_equal 'polo', res.body
46
+ end
47
+
48
+ @pool.post("/post", 'test=yes', {'X-Fancy-Header' => 'Sometimes'}) do |res|
49
+ assert_equal "200", res.code
50
+ assert_equal 'this is a test', res.body
51
+ end
52
+
53
+ @pool.put("/put", 'run=fast') do |res|
54
+ assert_equal "200", res.code
55
+ assert_equal 'fast', res.body
56
+ end
57
+
58
+ @pool.delete("/delete") do |res|
59
+ assert_equal "200", res.code
60
+ end
61
+ end
62
+
63
+ test "do not block main thread when resource is slow" do
64
+ start = Time.now
65
+ 5.times { @pool.get("/wait") {} }
66
+ assert Time.now - start < 20
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: net-http-pool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - elcuervo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-12 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: net-http-persistent
16
+ requirement: &70302928111800 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2.6'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70302928111800
25
+ - !ruby/object:Gem::Dependency
26
+ name: celluloid
27
+ requirement: &70302928111020 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.9.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70302928111020
36
+ - !ruby/object:Gem::Dependency
37
+ name: cutest
38
+ requirement: &70302928110440 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.1.3
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70302928110440
47
+ - !ruby/object:Gem::Dependency
48
+ name: capybara
49
+ requirement: &70302928109860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.1.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70302928109860
58
+ - !ruby/object:Gem::Dependency
59
+ name: mock-server
60
+ requirement: &70302928109300 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.1.2
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70302928109300
69
+ description:
70
+ email:
71
+ - yo@brunoaguirre.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - Gemfile
77
+ - README.md
78
+ - Rakefile
79
+ - SPEC.md
80
+ - lib/net/http/pool.rb
81
+ - net-http-pool.gemspec
82
+ - test/connections.rb
83
+ - test/pool.rb
84
+ homepage: http://github.com/elcuervo/net-http-pool
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 1.8.15
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Persistent pool of HTTP connections
108
+ test_files:
109
+ - test/connections.rb
110
+ - test/pool.rb