raindrops RubyGem user+dev discussion/patches/pulls/bugs/help
 help / Atom feed
* Raindrops::Middleware::Proxy claims to respond to #body when it does not?
@ 2012-05-17 19:07 Ben Somers
  2012-05-17 23:18 ` Eric Wong
  0 siblings, 1 reply; 4+ messages in thread
From: Ben Somers @ 2012-05-17 19:07 UTC (permalink / raw)
  To: raindrops

Hi,

Currently working on the auto-scaler for unicorn that I mentioned on
that mailing list back in January; I'm writing it as an external tool
that polls against the raindrops middleware to get a crude metric of
load. (Independently, I'd love your thoughts on whether that's a
viable/problematic approach; I think I can safely use the active
count, but details on exactly what those numbers mean would be cool).

In the process, though, I enabled Raindrops::Middleware on a whole
bunch of servers that weren't running it before, and started getting
some pretty weird errors on a few of them. Those boxes run a separate
middleware that writes xml requests to a log file; in the process,
they call #body on the response object. This works great when they're
receiving ActionController::Response objects from Rails, but blows up
on Raindrops::Middleware::Proxy objects.  What I'm seeing is that the
response passed to my logger middleware is a
Raindrops::Middleware::Proxy, with an ActionDispatch::Response set as
its @body. The ActionDispatch::Response responds to #body; the
Raindrops::Middleware::Proxy does not, since it has its body in a
plain instance variable without an accessor.

This tricked my initial workaround, which was to only log the body if
the response responded to #body, because the Middleware::Proxy winds
up claiming that it can respond when in fact it cannot. It does so
because it delegates :respond_to? to its body in almost all cases.

Clearly the Raindrops::Middleware::Proxy has #respond_to? implemented
the way it is for a reason, but it seems awfully counterintuitive.

Thoughts/answers? Not necessarily looking for any action here, just
trying to understand what's going on and why.

-ben

PS And yes, I'm totally aware that this logger middleware is dependent
on an interface not provided for in the Rack specification. I've
already complained to its author about this, though it probably falls
on me to correct that.
PPS Running on unicorn 4.3.1, raindrops 0.8.1, and rails 3.0.10, if
that's of any concern.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Raindrops::Middleware::Proxy claims to respond to #body when it does not?
  2012-05-17 19:07 Raindrops::Middleware::Proxy claims to respond to #body when it does not? Ben Somers
@ 2012-05-17 23:18 ` Eric Wong
  2012-05-17 23:37   ` Ben Somers
  0 siblings, 1 reply; 4+ messages in thread
From: Eric Wong @ 2012-05-17 23:18 UTC (permalink / raw)
  To: raindrops

Ben Somers <somers.ben@gmail.com> wrote:
> Hi,
> 
> Currently working on the auto-scaler for unicorn that I mentioned on
> that mailing list back in January;

Cool!

> I'm writing it as an external tool
> that polls against the raindrops middleware to get a crude metric of
> load. (Independently, I'd love your thoughts on whether that's a
> viable/problematic approach; I think I can safely use the active
> count, but details on exactly what those numbers mean would be cool).

active means, well, the active connections userspace knows about
(there's a valid file descriptor/Ruby IO object for it).
queued means the connections are in the kernel queues, and the
userspace app hasn't accept()-ed them, yet.

Unfortunately, I think polling is the least intrusive way, especially on
busy servers (the power usage won't be noticeable if your servers'
already busy).

> In the process, though, I enabled Raindrops::Middleware on a whole
> bunch of servers that weren't running it before, and started getting
> some pretty weird errors on a few of them. Those boxes run a separate
> middleware that writes xml requests to a log file; in the process,
> they call #body on the response object. This works great when they're
> receiving ActionController::Response objects from Rails, but blows up
> on Raindrops::Middleware::Proxy objects.  What I'm seeing is that the
> response passed to my logger middleware is a
> Raindrops::Middleware::Proxy, with an ActionDispatch::Response set as
> its @body. The ActionDispatch::Response responds to #body; the
> Raindrops::Middleware::Proxy does not, since it has its body in a
> plain instance variable without an accessor.
> 
> This tricked my initial workaround, which was to only log the body if
> the response responded to #body, because the Middleware::Proxy winds
> up claiming that it can respond when in fact it cannot. It does so
> because it delegates :respond_to? to its body in almost all cases.

Perhaps you can wrap the Middleware::Proxy response with a Rack::Response
object?  Rack::Response exposes :body as an accessor so it should be
compatible.  I think Rails uses/subclasses Rack::Response, too (but I'm
not remotely up-to-date on Rails internals).

> Clearly the Raindrops::Middleware::Proxy has #respond_to? implemented
> the way it is for a reason, but it seems awfully counterintuitive.

I think I took the hint from Rack::BodyProxy.  The response needs to be
proxied and call the #close method (to decrement the writer count).
Proxying the body is the only way to get a Rack server to call #close
(wrapping #each won't work because #to_path may be used instead)

Without the proxy, raindrops wouldn't be able to instrument (userspace)
time needed to write the response in a Rack-compliant fashion.

> Thoughts/answers? Not necessarily looking for any action here, just
> trying to understand what's going on and why.
> 
> -ben
> 
> PS And yes, I'm totally aware that this logger middleware is dependent
> on an interface not provided for in the Rack specification. I've
> already complained to its author about this, though it probably falls
> on me to correct that.

Yes, it sounds like this logger middleware needs to be fixed :)

> PPS Running on unicorn 4.3.1, raindrops 0.8.1, and rails 3.0.10, if
> that's of any concern.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Raindrops::Middleware::Proxy claims to respond to #body when it does not?
  2012-05-17 23:18 ` Eric Wong
@ 2012-05-17 23:37   ` Ben Somers
  2012-05-18  0:07     ` Eric Wong
  0 siblings, 1 reply; 4+ messages in thread
From: Ben Somers @ 2012-05-17 23:37 UTC (permalink / raw)
  To: raindrops

>> Clearly the Raindrops::Middleware::Proxy has #respond_to? implemented
>> the way it is for a reason, but it seems awfully counterintuitive.
>
> I think I took the hint from Rack::BodyProxy.  The response needs to be
> proxied and call the #close method (to decrement the writer count).
> Proxying the body is the only way to get a Rack server to call #close
> (wrapping #each won't work because #to_path may be used instead)
>
> Without the proxy, raindrops wouldn't be able to instrument (userspace)
> time needed to write the response in a Rack-compliant fashion.

That is sensible.

Would it make sense to take a second hint from Rack::BodyProxy and add
a #method_missing to Raindrops::Middleware::Proxy that delegates to
its body? I think that's the answer to my concern about an unintuitive
#respond_to? method.

http://rubydoc.info/github/rack/rack/master/Rack/BodyProxy:method_missing

-ben

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Raindrops::Middleware::Proxy claims to respond to #body when it does not?
  2012-05-17 23:37   ` Ben Somers
@ 2012-05-18  0:07     ` Eric Wong
  0 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2012-05-18  0:07 UTC (permalink / raw)
  To: raindrops

Ben Somers <somers.ben@gmail.com> wrote:
> Would it make sense to take a second hint from Rack::BodyProxy and add
> a #method_missing to Raindrops::Middleware::Proxy that delegates to
> its body? I think that's the answer to my concern about an unintuitive
> #respond_to? method.
> 
> http://rubydoc.info/github/rack/rack/master/Rack/BodyProxy:method_missing

Yes, it makes sense.  Care to send a patch + test?  Otherwise I'll get
to it tonight.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-17 19:07 Raindrops::Middleware::Proxy claims to respond to #body when it does not? Ben Somers
2012-05-17 23:18 ` Eric Wong
2012-05-17 23:37   ` Ben Somers
2012-05-18  0:07     ` Eric Wong

raindrops RubyGem user+dev discussion/patches/pulls/bugs/help

Archives are clonable:
	git clone --mirror https://bogomips.org/raindrops-public
	git clone --mirror http://ou63pmih66umazou.onion/raindrops-public

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops
	nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.raindrops

 note: .onion URLs require Tor: https://www.torproject.org/
       or Tor2web: https://www.tor2web.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox