Permalink
Browse files

Modify Rack::Mongoid::Middleware::IdentityMap to use new

Rack::Mongoid::Middleware::BodyProxy which calls its initialized block
after each() instead of close() as close() is not reliably called.
Also clear identity map if an exception is raised during
Rack::Mongoid::Middleware::IdentityMap#call().  [ fix #2445 ]
  • Loading branch information...
1 parent 22a0f8c commit 4fed822c3c5209f80aedbc6b3f943b189bffd6a8 Tim Olsen committed Nov 6, 2012
Showing with 37 additions and 1 deletion.
  1. +31 −0 lib/rack/mongoid/middleware/body_proxy.rb
  2. +6 −1 lib/rack/mongoid/middleware/identity_map.rb
@@ -0,0 +1,31 @@
+module Rack
+ module Mongoid
+ module Middleware
+
+ # Based on Rack::BodyProxy but overrides each() instead of close()
+ # as close() is not reliably called
+ class BodyProxy
+ def initialize(body, &block)
+ @body, @block, @finished = body, block, false
+ end
+
+ def respond_to?(*args)
+ super or @body.respond_to?(*args)
+ end
+
+ def each(*args, &block)
+ @body.each(*args, &block)
+ ensure
+ unless @finished
+ @finished = true
+ @block.call
+ end
+ end
+
+ def method_missing(*args, &block)
+ @body.__send__(*args, &block)
+ end
+ end
+ end
+ end
+end
@@ -32,10 +32,15 @@ def initialize(app)
# @since 2.1.0
def call(env)
response = @app.call(env)
- response[2] = ::Rack::BodyProxy.new(response[2]) do
+ response[2] = BodyProxy.new(response[2]) do
::Mongoid::IdentityMap.clear
end
response
+ rescue
+ # If we get here then the body will probably not be
+ # enumerated and we need to clear the identity map here
+ ::Mongoid::IdentityMap.clear
+ raise
end
# Passenger 3 does not execute the block provided to a Rack::BodyProxy

0 comments on commit 4fed822

Please sign in to comment.