sinatra-synchrony 0.1.0.beta.2 → 0.1.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.
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