em-http-request 1.0.0.beta.3 → 1.0.0.beta.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.

Potentially problematic release.


This version of em-http-request might be problematic. Click here for more details.

data/.gemtest ADDED
File without changes
data/Gemfile CHANGED
@@ -1,3 +1,14 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gemspec
3
+ gemspec
4
+
5
+ group :benchmark do
6
+ gem 'httparty'
7
+ gem 'rest-client'
8
+ gem 'tach', '0.0.8'
9
+ gem 'typhoeus'
10
+ gem 'sinatra'
11
+ gem 'streamly_ffi'
12
+ gem 'curb'
13
+ gem 'excon'
14
+ end
data/README.md CHANGED
@@ -11,8 +11,8 @@ Async (EventMachine) HTTP client, with support for:
11
11
  - HTTP proxy and SOCKS5 support
12
12
  - Basic Auth & OAuth
13
13
  - Connection-level & Global middleware support
14
- - Ryan Dahl's HTTP parser via [http_parser.rb](https://github.com/tmm1/http_parser.rb)
15
- - Works wherever EventMachine runs
14
+ - HTTP parser via [http_parser.rb](https://github.com/tmm1/http_parser.rb)
15
+ - Works wherever EventMachine runs: Rubinius, JRuby, MRI
16
16
 
17
17
  ## Getting started
18
18
 
data/Rakefile CHANGED
@@ -6,4 +6,5 @@ require 'rspec/core/rake_task'
6
6
  desc "Run all RSpec tests"
7
7
  RSpec::Core::RakeTask.new(:spec)
8
8
 
9
- task :default => :spec
9
+ task :default => :spec
10
+ task :test => [:spec]
@@ -0,0 +1,156 @@
1
+ $: << './benchmarks'
2
+ require 'server'
3
+
4
+ require 'excon'
5
+ require 'httparty'
6
+ require 'net/http'
7
+ require 'open-uri'
8
+ require 'rest_client'
9
+ require 'tach'
10
+ require 'typhoeus'
11
+
12
+ url = 'http://127.0.0.1/10k.html'
13
+
14
+ with_server do
15
+ Tach.meter(100) do
16
+
17
+ tach('curb (persistent)') do |n|
18
+ curb = Curl::Easy.new
19
+
20
+ n.times do
21
+ curb.url = url
22
+ curb.http_get
23
+ curb.body_str
24
+ end
25
+ end
26
+
27
+ tach('em-http-request') do |n|
28
+ EventMachine.run {
29
+ count = 0
30
+ error = 0
31
+
32
+ n.times do
33
+ http = EventMachine::HttpRequest.new(url).get
34
+
35
+ http.callback {
36
+ count += 1
37
+ if count == n
38
+ p [count, error]
39
+ EM.stop
40
+ end
41
+ }
42
+
43
+ http.errback {
44
+ count += 1
45
+ error += 1
46
+ if count == n
47
+ p [count, error]
48
+ EM.stop
49
+ end
50
+ }
51
+ end
52
+ }
53
+ end
54
+
55
+ tach('em-http-request (persistent)') do |n|
56
+ EventMachine.run {
57
+ count = 0
58
+ error = 0
59
+
60
+ conn = EventMachine::HttpRequest.new(url)
61
+
62
+ n.times do
63
+ http = conn.get :keepalive => true
64
+ http.callback {
65
+ count += 1
66
+ if count == n
67
+ p [count, error]
68
+ EM.stop
69
+ end
70
+ }
71
+
72
+ http.errback {
73
+ count += 1
74
+ error += 1
75
+ if count == n
76
+ p [count, error]
77
+ EM.stop
78
+ end
79
+ }
80
+ end
81
+ }
82
+ end
83
+
84
+ tach('Excon') do
85
+ Excon.get(url).body
86
+ end
87
+
88
+ excon = Excon.new(url)
89
+ tach('Excon (persistent)') do
90
+ excon.request(:method => 'get').body
91
+ end
92
+
93
+ tach('HTTParty') do
94
+ HTTParty.get(url).body
95
+ end
96
+
97
+ uri = Addressable::URI.parse(url)
98
+ tach('Net::HTTP') do
99
+ Net::HTTP.start(uri.host, uri.port) {|http| http.get(uri.path).body }
100
+ end
101
+
102
+ uri = Addressable::URI.parse(url)
103
+ Net::HTTP.start(uri.host, uri.port) do |http|
104
+ tach('Net::HTTP (persistent)') do
105
+ http.get(uri.path).body
106
+ end
107
+ end
108
+
109
+ tach('open-uri') do
110
+ open(url).read
111
+ end
112
+
113
+ tach('RestClient') do
114
+ RestClient.get(url)
115
+ end
116
+
117
+ streamly = StreamlyFFI::Connection.new
118
+ tach('StreamlyFFI (persistent)') do
119
+ streamly.get(url)
120
+ end
121
+
122
+ tach('Typhoeus') do
123
+ Typhoeus::Request.get(url).body
124
+ end
125
+
126
+ end
127
+ end
128
+
129
+
130
+ # +------------------------------+----------+
131
+ # | tach | total |
132
+ # +------------------------------+----------+
133
+ # | em-http-request (persistent) | 0.016779 |
134
+ # +------------------------------+----------+
135
+ # | Excon (persistent) | 0.019606 |
136
+ # +------------------------------+----------+
137
+ # | curb (persistent) | 0.022034 |
138
+ # +------------------------------+----------+
139
+ # | Typhoeus | 0.027276 |
140
+ # +------------------------------+----------+
141
+ # | Excon | 0.034482 |
142
+ # +------------------------------+----------+
143
+ # | StreamlyFFI (persistent) | 0.036474 |
144
+ # +------------------------------+----------+
145
+ # | em-http-request | 0.041866 |
146
+ # +------------------------------+----------+
147
+ # | Net::HTTP (persistent) | 0.098379 |
148
+ # +------------------------------+----------+
149
+ # | Net::HTTP | 0.103786 |
150
+ # +------------------------------+----------+
151
+ # | RestClient | 0.111841 |
152
+ # +------------------------------+----------+
153
+ # | HTTParty | 0.118632 |
154
+ # +------------------------------+----------+
155
+ # | open-uri | 0.170172 |
156
+ # +------------------------------+----------+
@@ -0,0 +1,87 @@
1
+ $: << './benchmarks'
2
+ require 'server'
3
+
4
+ url = 'http://127.0.0.1/10k.html'
5
+
6
+ with_server do
7
+ Tach.meter(100) do
8
+
9
+ excon = Excon.new(url)
10
+ tach('Excon (persistent)') do
11
+ excon.request(:method => 'get').body
12
+ end
13
+
14
+ tach('Excon') do
15
+ Excon.get(url).body
16
+ end
17
+
18
+ tach('em-http-request') do |n|
19
+ EventMachine.run {
20
+ count = 0
21
+ error = 0
22
+ n.times do
23
+ EM.next_tick do
24
+ http = EventMachine::HttpRequest.new(url, :connect_timeout => 1).get
25
+
26
+ http.callback {
27
+ count += 1
28
+ if count == n
29
+ p [count, error]
30
+ EM.stop
31
+ end
32
+ }
33
+
34
+ http.errback {
35
+ count += 1
36
+ error += 1
37
+ if count == n
38
+ p [count, error]
39
+ EM.stop
40
+ end
41
+ }
42
+ end
43
+ end
44
+ }
45
+ end
46
+
47
+ tach('em-http-request (persistent)') do |n|
48
+ EventMachine.run {
49
+ count = 0
50
+ error = 0
51
+ conn = EventMachine::HttpRequest.new(url)
52
+
53
+ n.times do
54
+ http = conn.get :keepalive => true
55
+ http.callback {
56
+ count += 1
57
+ if count == n
58
+ p [count, error]
59
+ EM.stop
60
+ end
61
+ }
62
+
63
+ http.errback {
64
+ count += 1
65
+ error += 1
66
+ if count == n
67
+ p [count, error]
68
+ EM.stop
69
+ end
70
+ }
71
+ end
72
+ }
73
+ end
74
+ end
75
+ end
76
+
77
+ # +------------------------------+----------+
78
+ # | tach | total |
79
+ # +------------------------------+----------+
80
+ # | em-http-request (persistent) | 0.018133 |
81
+ # +------------------------------+----------+
82
+ # | Excon (persistent) | 0.023975 |
83
+ # +------------------------------+----------+
84
+ # | Excon | 0.032877 |
85
+ # +------------------------------+----------+
86
+ # | em-http-request | 0.042891 |
87
+ # +------------------------------+----------+
Binary file
@@ -0,0 +1,65 @@
1
+ Total: 143 samples
2
+ 67 46.9% 46.9% 109 76.2% Kernel#gem_original_require
3
+ 17 11.9% 58.7% 17 11.9% garbage_collector
4
+ 12 8.4% 67.1% 12 8.4% EventMachine.connect_server
5
+ 11 7.7% 74.8% 11 7.7% Dir.[]
6
+ 11 7.7% 82.5% 11 7.7% File.file?
7
+ 4 2.8% 85.3% 4 2.8% Kernel#eval
8
+ 3 2.1% 87.4% 16 11.2% Enumerable#find
9
+ 3 2.1% 89.5% 3 2.1% Regexp#initialize
10
+ 2 1.4% 90.9% 16 11.2% EventMachine.run_machine
11
+ 2 1.4% 92.3% 2 1.4% Regexp#match
12
+ 1 0.7% 93.0% 1 0.7% FFI::DynamicLibrary.open
13
+ 1 0.7% 93.7% 1 0.7% Hash#values
14
+ 1 0.7% 94.4% 7 4.9% Kernel#load
15
+ 1 0.7% 95.1% 3 2.1% MIME::Type#initialize
16
+ 1 0.7% 95.8% 1 0.7% MatchData#captures
17
+ 1 0.7% 96.5% 13 9.1% Module#bind_connect
18
+ 1 0.7% 97.2% 17 11.9% Module#searcher
19
+ 1 0.7% 97.9% 1 0.7% String#downcase
20
+ 1 0.7% 98.6% 1 0.7% String#scan
21
+ 1 0.7% 99.3% 1 0.7% String#strip
22
+ 1 0.7% 100.0% 1 0.7% TCPSocket#initialize
23
+ 0 0.0% 100.0% 1 0.7% Array#map
24
+ 0 0.0% 100.0% 14 9.8% Array#reverse_each
25
+ 0 0.0% 100.0% 14 9.8% Class#from_gems_in
26
+ 0 0.0% 100.0% 14 9.8% Class#from_installed_gems
27
+ 0 0.0% 100.0% 14 9.8% Class#load
28
+ 0 0.0% 100.0% 1 0.7% Class#parse
29
+ 0 0.0% 100.0% 1 0.7% Class#simplified
30
+ 0 0.0% 100.0% 6 4.2% Enumerable#each_with_index
31
+ 0 0.0% 100.0% 1 0.7% Excon::Connection#connect
32
+ 0 0.0% 100.0% 1 0.7% Excon::Connection#request
33
+ 0 0.0% 100.0% 1 0.7% Excon::Connection#socket
34
+ 0 0.0% 100.0% 1 0.7% FFI::Library#ffi_lib
35
+ 0 0.0% 100.0% 10 7.0% Gem::GemPathSearcher#find
36
+ 0 0.0% 100.0% 1 0.7% Gem::GemPathSearcher#find_active
37
+ 0 0.0% 100.0% 16 11.2% Gem::GemPathSearcher#init_gemspecs
38
+ 0 0.0% 100.0% 16 11.2% Gem::GemPathSearcher#initialize
39
+ 0 0.0% 100.0% 11 7.7% Gem::GemPathSearcher#matching_file?
40
+ 0 0.0% 100.0% 11 7.7% Gem::GemPathSearcher#matching_files
41
+ 0 0.0% 100.0% 14 9.8% Gem::SourceIndex#load_gems_in
42
+ 0 0.0% 100.0% 14 9.8% Gem::SourceIndex#refresh!
43
+ 0 0.0% 100.0% 1 0.7% Gem::SourceIndex#search
44
+ 0 0.0% 100.0% 1 0.7% HttpOptions#initialize
45
+ 0 0.0% 100.0% 1 0.7% HttpOptions#set_uri
46
+ 0 0.0% 100.0% 14 9.8% Integer#times
47
+ 0 0.0% 100.0% 1 0.7% Kernel#loop
48
+ 0 0.0% 100.0% 109 76.2% Kernel#require
49
+ 0 0.0% 100.0% 1 0.7% Module#activate
50
+ 0 0.0% 100.0% 13 9.1% Module#connect
51
+ 0 0.0% 100.0% 1 0.7% Module#get
52
+ 0 0.0% 100.0% 2 1.4% Module#load_full_rubygems_library
53
+ 0 0.0% 100.0% 5 3.5% Module#loaded_path?
54
+ 0 0.0% 100.0% 16 11.2% Module#meter
55
+ 0 0.0% 100.0% 16 11.2% Module#run
56
+ 0 0.0% 100.0% 16 11.2% Module#source_index
57
+ 0 0.0% 100.0% 30 21.0% Module#try_activate
58
+ 0 0.0% 100.0% 17 11.9% Object#with_server
59
+ 0 0.0% 100.0% 2 1.4% Regexp.union
60
+ 0 0.0% 100.0% 1 0.7% TCPSocket.open
61
+ 0 0.0% 100.0% 16 11.2% Tach::Meter#initialize
62
+ 0 0.0% 100.0% 16 11.2% Tach::Meter#run_tach
63
+ 0 0.0% 100.0% 1 0.7% URI::Parser#initialize
64
+ 0 0.0% 100.0% 1 0.7% URI::Parser#initialize_regexp
65
+ 0 0.0% 100.0% 7 4.9% YAML::EngineManager#yamler=
@@ -0,0 +1,48 @@
1
+ require 'excon'
2
+ require 'httparty'
3
+ require 'net/http'
4
+ require 'open-uri'
5
+ require 'rest_client'
6
+ require 'tach'
7
+ require 'typhoeus'
8
+ require 'sinatra/base'
9
+ require 'streamly_ffi'
10
+ require 'curb'
11
+
12
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'em-http')
13
+
14
+ module Benchmark
15
+ class Server < Sinatra::Base
16
+
17
+ def self.run
18
+ Rack::Handler::WEBrick.run(
19
+ Benchmark::Server.new,
20
+ :Port => 9292,
21
+ :AccessLog => [],
22
+ :Logger => WEBrick::Log.new(nil, WEBrick::Log::ERROR)
23
+ )
24
+ end
25
+
26
+ get '/data/:amount' do |amount|
27
+ 'x' * amount.to_i
28
+ end
29
+
30
+ end
31
+ end
32
+
33
+ def with_server(&block)
34
+ pid = Process.fork do
35
+ # Benchmark::Server.run
36
+ end
37
+ loop do
38
+ sleep(1)
39
+ begin
40
+ # Excon.get('http://localhost:9292/api/foo')
41
+ break
42
+ rescue
43
+ end
44
+ end
45
+ yield
46
+ ensure
47
+ Process.kill(9, pid)
48
+ end
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.description = s.summary
15
15
  s.rubyforge_project = "em-http-request"
16
16
 
17
- s.add_dependency "eventmachine"
17
+ s.add_dependency "eventmachine", ">= 1.0.0.beta.3"
18
18
  s.add_dependency "addressable", ">= 2.2.3"
19
19
  s.add_dependency "http_parser.rb", ">= 0.5.1"
20
20
  s.add_dependency "em-socksify"
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.add_development_dependency "rake"
24
24
  s.add_development_dependency "rack"
25
25
  s.add_development_dependency "yajl-ruby"
26
+ s.add_development_dependency "cookiejar"
26
27
  s.add_development_dependency "mongrel", "~> 1.2.0.pre2"
27
28
 
28
29
  s.files = `git ls-files`.split("\n")
@@ -0,0 +1 @@
1
+ twitter_auth.rb
@@ -9,17 +9,21 @@ def async_fetch(url)
9
9
  f = Fiber.current
10
10
  http = EventMachine::HttpRequest.new(url).get :timeout => 10
11
11
 
12
- http.callback { f.resume(http) }
13
- http.errback { f.resume(http) }
14
-
15
- return Fiber.yield
12
+ if http.error.empty?
13
+ http.callback { f.resume(http) }
14
+ http.errback { f.resume(http) }
15
+
16
+ Fiber.yield
17
+ else
18
+ http
19
+ end
16
20
  end
17
21
 
18
22
  EventMachine.run do
19
23
  Fiber.new{
20
24
 
21
25
  puts "Setting up HTTP request #1"
22
- data = async_fetch('http://www.google.com/')
26
+ data = async_fetch('http://www.google.moo/')
23
27
  puts "Fetched page #1: #{data.response_header.status}"
24
28
 
25
29
  puts "Setting up HTTP request #2"
@@ -36,4 +40,4 @@ puts "Done"
36
40
  # Fetched page #1: 302
37
41
  # Setting up HTTP request #2
38
42
  # Fetched page #2: 200
39
- # Done
43
+ # Done