sinatra-synchrony 0.1.0.beta.2 → 0.1.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source :rubygems
2
2
 
3
- gemspec
3
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sinatra-synchrony (0.0.3)
5
- async-rack (= 0.5.1)
4
+ sinatra-synchrony (0.1.0.beta.2)
6
5
  em-http-request (= 0.3.0)
7
6
  em-resolv-replace (= 1.1.1)
8
7
  em-synchrony (= 0.2.0)
@@ -18,9 +17,7 @@ GEM
18
17
  RubyInline (3.9.0)
19
18
  ZenTest (~> 4.3)
20
19
  ZenTest (4.5.0)
21
- addressable (2.2.5)
22
- async-rack (0.5.1)
23
- rack (~> 1.1)
20
+ addressable (2.2.6)
24
21
  diff-lcs (1.1.2)
25
22
  em-http-request (0.3.0)
26
23
  addressable (>= 2.0.0)
@@ -55,7 +52,7 @@ GEM
55
52
  ruby_parser (>= 2.0.5)
56
53
  sexp_processor (>= 3.0.5)
57
54
  spruz (0.2.6)
58
- tilt (1.3)
55
+ tilt (1.3.2)
59
56
  wrong (0.5.0)
60
57
  ParseTree (~> 3.0)
61
58
  diff-lcs (~> 1.1.2)
data/README.markdown CHANGED
@@ -43,14 +43,31 @@ If you are developing with a classic style app, just require the gem and it will
43
43
  'Sinatra::Synchrony is loaded automatically in classic mode, nothing needed'
44
44
  end
45
45
 
46
+ Net::HTTP / TCPSocket
47
+ ---
48
+ If you're using anything based on TCPSocket (such as Net::HTTP, which is used by many things), you can replace the native Ruby TCPSocket with one that supports EventMachine and allows for concurrency:
49
+
50
+ Sinatra::Synchrony.overload_tcpsocket!
51
+
52
+ This will allow you to use things like [RestClient](https://github.com/archiloque/rest-client) without any changes:
53
+
54
+ RestClient.get 'http://google.com'
55
+
56
+ This is not perfect though - the TCPSocket overload doesn't currently support SSL and will throw an exception. This is more for when you have ruby libraries that use Net::HTTP and you want to try something. If you intend to do HTTP requests, I strongly recommend using [Faraday](https://github.com/technoweenie/faraday) instead, which has support for [EM-HTTP-Request](https://github.com/igrigorik/em-http-request).
57
+
58
+ Please encourage Ruby library developers to use (or at least support) Faraday instead of Net::HTTP. Aside from the inability to be concurrent natively, it's a pretty weird and crappy interface, which makes it harder to replace it with something better.
59
+
46
60
  Tests
47
61
  ---
62
+ Add this to the top of your test file:
48
63
 
49
- Just write your tests as usual, my Rack::Test patch fixes the "outside of EventMachine" errors. You must be in the __test__ environment so that Sinatra will not load Rack::FiberPool. My patch admittedly needs some work.
64
+ Sinatra::Synchrony.patch_tests!
65
+
66
+ Then just write your tests as usual, and all tests will be run within EventMachine. You must be in the __test__ environment so that Sinatra will not load Rack::FiberPool.
50
67
 
51
68
  Benchmarks
52
69
  ---
53
- It's pretty fast!
70
+ Despite enabling synchronous programming without callbacks, there is no performance hit to your application! All the performance benefits you expect from Thin/Rainbows and EventMachine are still there:
54
71
 
55
72
  class App < Sinatra::Base
56
73
  register Sinatra::Synchrony
@@ -59,7 +76,7 @@ It's pretty fast!
59
76
  end
60
77
  end
61
78
 
62
- run with rackup -s thin:
79
+ Benchmarked with rackup -s thin:
63
80
 
64
81
  $ ab -c 50 -n 2000 http://127.0.0.1:9292/
65
82
  ...
@@ -76,24 +93,22 @@ run with rackup -s thin:
76
93
 
77
94
  Let's try a simple blocking IO example to prove it works. 100 hits to google.com:
78
95
 
96
+ require 'sinatra'
97
+ require 'sinatra/synchrony'
79
98
  require 'rest-client'
80
-
81
- class App < Sinatra::Base
82
- register Sinatra::Synchrony
83
- get '/' do
84
- # Using EventMachine::HttpRequest
85
- # EM::Synchrony.sync(EventMachine::HttpRequest.new('http://google.com').get).response
99
+ require 'faraday'
100
+ Faraday.default_adapter = :em_synchrony
86
101
 
87
- # Using RestClient, which gets concurrency via patched TCPSocket, no changes required!
88
- RestClient.get 'http://google.com'
89
- end
102
+ get '/' do
103
+ Faraday.get 'http://google.com'
90
104
  end
91
105
 
106
+
92
107
  $ ab -c 100 -n 100 http://127.0.0.1:9292/
93
108
  ...
94
- Time taken for tests: 1.270 seconds
95
-
96
- For a perspective, this operation takes __33 seconds__ without this extension. That's __26x__ faster!
109
+ Time taken for tests: 0.256 seconds
110
+
111
+ For a perspective, this operation takes __33 seconds__ without this extension.
97
112
 
98
113
  Geoloqi
99
114
  ---
@@ -101,9 +116,7 @@ This gem was designed to help us develop faster games and internal applications
101
116
 
102
117
  TODO / Thoughts
103
118
  ---
104
- * This is fairly new, though we are using it in production without any problems. Test before deploying anything with it.
105
- * Provide better method for patching Rack::Test that's less fragile to version changes. This is a big priority and I intend to improve this. Pull requests here welcome!
106
- * Research way to run tests with Rack::FiberPool enabled.
119
+ * We are using this in production without any problems, and it's very stable for us. But you should test before deploying anything with it.
107
120
  * There is work underway to make this a Rack middleware, and integrate that middleware with this plugin. That way, many other frameworks can take advantage of this. There is also work exploratory work to provide support for non-EventMachine Reactor pattern implementations with this approach, but it's beyond the scope of this extension.
108
121
 
109
122
  Author
@@ -4,7 +4,6 @@ require 'eventmachine'
4
4
  require 'em-http-request'
5
5
  require 'em-synchrony'
6
6
  require 'em-resolv-replace'
7
- require 'net/http'
8
7
 
9
8
  module Sinatra
10
9
  module Synchrony
@@ -12,6 +11,16 @@ module Sinatra
12
11
  builder.use Rack::FiberPool unless test?
13
12
  super
14
13
  end
14
+
15
+ class << self
16
+ def patch_tests!
17
+ require 'sinatra/synchrony/mock_session'
18
+ end
19
+
20
+ def overload_tcpsocket!
21
+ require 'sinatra/synchrony/tcpsocket'
22
+ end
23
+ end
15
24
  end
16
25
  register Synchrony
17
- end
26
+ end
@@ -0,0 +1,13 @@
1
+ require 'rack/test'
2
+
3
+ module Rack
4
+ class MockSession
5
+ alias_method :request_original, :request
6
+ def request(uri, env)
7
+ EM.synchrony do
8
+ request_original uri, env
9
+ EM.stop
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ require 'net/http'
2
+
3
+ original_verbosity = $VERBOSE
4
+ $VERBOSE = nil
5
+ TCPSocket = EventMachine::Synchrony::TCPSocket
6
+ $VERBOSE = original_verbosity
@@ -1,8 +1,9 @@
1
1
  ENV['RACK_ENV'] = 'test'
2
2
  require File.join(File.join(File.expand_path(File.dirname(__FILE__))), '..', 'lib', 'sinatra', 'synchrony')
3
- require File.join(File.join(File.expand_path(File.dirname(__FILE__))), '..', 'lib', 'rack', 'test_synchrony')
3
+ require 'rack/test'
4
4
  require 'minitest/autorun'
5
5
  require 'wrong/adapters/minitest'
6
+ Sinatra::Synchrony.patch_tests!
6
7
  Wrong.config.alias_assert :expect
7
8
 
8
9
  def mock_app(base=Sinatra::Base, &block)
@@ -40,4 +41,4 @@ describe 'A mock app' do
40
41
  expect { last_response.ok? }
41
42
  expect { last_response.headers['Set-Cookie'] }
42
43
  end
43
- end
44
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-synchrony
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196407
4
+ hash: 62196411
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
9
  - 0
10
10
  - beta
11
- - 2
12
- version: 0.1.0.beta.2
11
+ - 4
12
+ version: 0.1.0.beta.4
13
13
  platform: ruby
14
14
  authors:
15
15
  - Kyle Drake
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-07-11 00:00:00 Z
20
+ date: 2011-08-01 00:00:00 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: sinatra
@@ -168,8 +168,9 @@ extensions: []
168
168
  extra_rdoc_files: []
169
169
 
170
170
  files:
171
+ - lib/sinatra/synchrony/mock_session.rb
172
+ - lib/sinatra/synchrony/tcpsocket.rb
171
173
  - lib/sinatra/synchrony.rb
172
- - lib/rack/test_synchrony.rb
173
174
  - spec/synchrony_spec.rb
174
175
  - Gemfile
175
176
  - Gemfile.lock
@@ -1,25 +0,0 @@
1
- require 'rack/test'
2
- # Monkeypatch to provide EM within tests.
3
- # If you have a better approach, please send a pull request!
4
-
5
- module Rack
6
- class MockSession
7
- def request(uri, env)
8
- env["HTTP_COOKIE"] ||= cookie_jar.for(uri)
9
- @last_request = Rack::Request.new(env)
10
- EM.synchrony do
11
- status, headers, body = @app.call(@last_request.env)
12
- @last_response = MockResponse.new(status, headers, body, env["rack.errors"].flush)
13
- body.close if body.respond_to?(:close)
14
- cookie_jar.merge(last_response.headers["Set-Cookie"], uri)
15
- @after_request.each { |hook| hook.call }
16
- if @last_response.respond_to?(:finish)
17
- @last_response.finish
18
- else
19
- @last_response
20
- end
21
- EM.stop
22
- end
23
- end
24
- end
25
- end