async-rack 0.4.0.c → 0.4.0.d
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/README.md +43 -0
- data/lib/async_rack.rb +9 -4
- data/lib/async_rack/async_callback.rb +7 -2
- data/lib/async_rack/catch_async.rb +16 -0
- data/lib/async_rack/session/cookie.rb +1 -1
- data/lib/async_rack/session/memcache.rb +1 -1
- data/lib/async_rack/session/pool.rb +1 -1
- data/lib/async_rack/throw_async.rb +17 -0
- data/spec/async_rack/async_callback_spec.rb +1 -3
- metadata +5 -3
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# AsyncRack
|
2
2
|
|
3
|
+
## Note upfront
|
4
|
+
Still experimental. Feel free to play around.
|
5
|
+
|
6
|
+
## Introduction
|
3
7
|
So, have you been amazed by thin's `async.callback`? If not, [go](http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin/) [check](http://github.com/raggi/async_sinatra) [it](http://github.com/raggi/thin/blob/async_for_rack/example/async_app.ru) [out](http://m.onkey.org/2010/1/7/introducing-cramp). Come back here when you start missing your middleware.
|
4
8
|
|
5
9
|
So what is the issue with Rack and `async.callback`? Currently there are two ways of triggering a async responds. The first is to `throw :async`, the latter to return a status code of -1 (even though thin and ebb do disagree on that). Opposed to what others say, I would recommend using `throw`, as it simply skips middleware not able to handle `:async`. Also, it works on all servers supporting `async.callback` – thin, ebb, rainbows! and zbatery – about the same and copes better with middleware that is unable to handle an async respond.
|
@@ -30,6 +34,45 @@ How does that work? Simple, whenever necessary, `async-rack` will replace `async
|
|
30
34
|
|
31
35
|
Note: This library only 'fixes' the middleware that ships with rack, not other rack middleware. However, you can use the included helper classes to easily make other libraries handle `async.callback`.
|
32
36
|
|
37
|
+
## What's in this package?
|
38
|
+
|
39
|
+
### Rack middleware made async-proof
|
40
|
+
This middleware now works well with `throw :async`:
|
41
|
+
|
42
|
+
* Rack::Chunked
|
43
|
+
* Rack::CommonLogger
|
44
|
+
* Rack::ConditionalGet
|
45
|
+
* Rack::ContentLength
|
46
|
+
* Rack::ContentType
|
47
|
+
* Rack::Deflater
|
48
|
+
* Rack::ETag
|
49
|
+
* Rack::Head
|
50
|
+
* Rack::Logger
|
51
|
+
* Rack::Runtime
|
52
|
+
* Rack::Sendfile
|
53
|
+
* Rack::ShowStatus
|
54
|
+
|
55
|
+
### Middleware that is async-proof out of the box
|
56
|
+
No changes where necessary for:
|
57
|
+
|
58
|
+
* Rack::Cascade
|
59
|
+
* Rack::Config
|
60
|
+
* Rack::Directory
|
61
|
+
* Rack::File
|
62
|
+
* Rack::MethodOverride
|
63
|
+
* Rack::Mime
|
64
|
+
* Rack::NullLogger
|
65
|
+
* Rack::Recursive
|
66
|
+
* Rack::Reloader
|
67
|
+
* Rack::Static
|
68
|
+
* Rack::URLMap
|
69
|
+
|
70
|
+
### Middleware not (yet) made async-proof
|
71
|
+
|
72
|
+
* Rack::Lint (might not check async responses)
|
73
|
+
* Rack::ShowExceptions (might not show exceptions for async responses)
|
74
|
+
* Rack::Lock (might raise an exception)
|
75
|
+
|
33
76
|
## How to make a middleware async-proof?
|
34
77
|
There are three types of middleware:
|
35
78
|
|
data/lib/async_rack.rb
CHANGED
@@ -13,13 +13,19 @@ module AsyncRack
|
|
13
13
|
module ExtensionMixin
|
14
14
|
::AsyncRack.extend self
|
15
15
|
def autoload(class_name, path)
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
if Rack.const_defined? class_name
|
17
|
+
require path
|
18
|
+
else
|
19
|
+
Rack.autoload class_name, path
|
20
|
+
super
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
25
|
+
# New middleware
|
26
|
+
autoload :CatchAsync, "async_rack/catch_async"
|
27
|
+
autoload :ThrowAsync, "async_rack/throw_async"
|
28
|
+
|
23
29
|
# Wrapped rack middleware
|
24
30
|
autoload :Chunked, "async_rack/chunked"
|
25
31
|
autoload :CommonLogger, "async_rack/commonlogger"
|
@@ -31,7 +37,6 @@ module AsyncRack
|
|
31
37
|
autoload :Head, "async_rack/head"
|
32
38
|
autoload :Lock, "async_rack/lock"
|
33
39
|
autoload :Logger, "async_rack/logger"
|
34
|
-
# autoload :Recursive, "async_rack/recursive"
|
35
40
|
autoload :Runtime, "async_rack/runtime"
|
36
41
|
autoload :Sendfile, "async_rack/sendfile"
|
37
42
|
autoload :ShowStatus, "async_rack/showstatus"
|
@@ -27,6 +27,10 @@ module AsyncRack
|
|
27
27
|
# Rack::FancyMiddleware # => AsyncRack::FancyMiddleware
|
28
28
|
# AsyncRack::FancyMiddleware.ancestors # => [AsyncRack::AsyncCallback::Mixin, Rack::FancyMiddleware, ...]
|
29
29
|
module AsyncCallback
|
30
|
+
def self.included(mod)
|
31
|
+
mod.send :include, Mixin
|
32
|
+
super
|
33
|
+
end
|
30
34
|
|
31
35
|
##
|
32
36
|
# Aliases a subclass on subclassing, but only once.
|
@@ -82,9 +86,9 @@ module AsyncRack
|
|
82
86
|
private
|
83
87
|
def setup_late_initialize(klass)
|
84
88
|
class << klass
|
85
|
-
alias create new
|
86
89
|
def new(*args, &block)
|
87
|
-
|
90
|
+
return super if File.expand_path(caller.first[/^[^:]+/]) == File.expand_path(__FILE__)
|
91
|
+
proc { |env| new(*args, &block).call(env) }
|
88
92
|
end
|
89
93
|
end
|
90
94
|
end
|
@@ -92,6 +96,7 @@ module AsyncRack
|
|
92
96
|
|
93
97
|
module Mixin
|
94
98
|
extend LateInitializer
|
99
|
+
attr_accessor :env
|
95
100
|
|
96
101
|
def async_callback(result)
|
97
102
|
@async_callback.call result
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rack'
|
2
|
+
module AsyncRack
|
3
|
+
class CatchAsync
|
4
|
+
Rack::CatchAsync = self unless defined? Rack::CatchAsync
|
5
|
+
|
6
|
+
def initialize(app, async_response = [-1, {}, []])
|
7
|
+
@app, @async_response = app, async_response
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
response = @async_response
|
12
|
+
catch(:async) { response = @app.call env }
|
13
|
+
response
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module AsyncRack
|
4
|
+
class ThrowAsync
|
5
|
+
Rack::ThrowAsync = self unless defined? Rack::ThrowAsync
|
6
|
+
|
7
|
+
def initialize(app, throw_on = [-1, 0])
|
8
|
+
@app, @throw_on = app, throw_on
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
response = @app.call env
|
13
|
+
throw :async if @throw_on.include? response.first
|
14
|
+
response
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -28,7 +28,6 @@ describe AsyncRack::AsyncCallback do
|
|
28
28
|
before do
|
29
29
|
@class = Class.new do
|
30
30
|
include AsyncRack::AsyncCallback::SimpleWrapper
|
31
|
-
attr_accessor :app, :env
|
32
31
|
class << self
|
33
32
|
attr_accessor :instance
|
34
33
|
end
|
@@ -44,8 +43,7 @@ describe AsyncRack::AsyncCallback do
|
|
44
43
|
end
|
45
44
|
|
46
45
|
it "runs #call again on async callback, replacing app" do
|
47
|
-
middleware = @class.create
|
48
|
-
middleware.app = proc { throw :async }
|
46
|
+
middleware = @class.create proc { throw :async }
|
49
47
|
catch(:async) do
|
50
48
|
middleware.call "async.callback" => proc { |x| x + 10 }
|
51
49
|
raise "should not get here"
|
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 0
|
7
7
|
- 4
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.4.0.
|
9
|
+
- d
|
10
|
+
version: 0.4.0.d
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Konstantin Haase
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-03-
|
18
|
+
date: 2010-03-14 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -57,6 +57,7 @@ extra_rdoc_files: []
|
|
57
57
|
files:
|
58
58
|
- lib/async-rack.rb
|
59
59
|
- lib/async_rack/async_callback.rb
|
60
|
+
- lib/async_rack/catch_async.rb
|
60
61
|
- lib/async_rack/chunked.rb
|
61
62
|
- lib/async_rack/commonlogger.rb
|
62
63
|
- lib/async_rack/conditionalget.rb
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- lib/async_rack/session/memcache.rb
|
74
75
|
- lib/async_rack/session/pool.rb
|
75
76
|
- lib/async_rack/showstatus.rb
|
77
|
+
- lib/async_rack/throw_async.rb
|
76
78
|
- lib/async_rack.rb
|
77
79
|
- spec/async_rack/async_callback_spec.rb
|
78
80
|
- spec/spec_helper.rb
|