net-http-pool 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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