From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: * X-Spam-ASN: AS14383 205.234.109.0/24 X-Spam-Status: No, score=1.0 required=3.0 tests=AWL,HK_RANDOM_FROM, MSGID_FROM_MTA_HEADER shortcircuit=no autolearn=no version=3.3.2 Path: news.gmane.org!not-for-mail From: Eric Wong Newsgroups: gmane.comp.lang.ruby.rainbows.general Subject: notes for streaming responses with Rails 3.1 Date: Wed, 27 Apr 2011 15:32:43 -0700 Message-ID: <20110427223243.GA32368@dcvr.yhbt.net> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1303943577 2408 80.91.229.12 (27 Apr 2011 22:32:57 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 27 Apr 2011 22:32:57 +0000 (UTC) To: rainbows-talk-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org Original-X-From: rainbows-talk-bounces-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org Thu Apr 28 00:32:52 2011 Return-path: Envelope-to: gclrrg-rainbows-talk@m.gmane.org X-Original-To: rainbows-talk-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org Delivered-To: rainbows-talk-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) X-BeenThere: rainbows-talk-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: rainbows-talk-bounces-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org Errors-To: rainbows-talk-bounces-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org Xref: news.gmane.org gmane.comp.lang.ruby.rainbows.general:229 Archived-At: Received: from rubyforge.org ([205.234.109.19]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1QFDHv-0005bi-Bo for gclrrg-rainbows-talk@m.gmane.org; Thu, 28 Apr 2011 00:32:51 +0200 Received: from rubyforge.org (rubyforge.org [127.0.0.1]) by rubyforge.org (Postfix) with ESMTP id BDA921858387; Wed, 27 Apr 2011 18:32:50 -0400 (EDT) Received: from dcvr.yhbt.net (dcvr.yhbt.net [64.71.152.64]) by rubyforge.org (Postfix) with ESMTP id 4977C1858377 for ; Wed, 27 Apr 2011 18:32:46 -0400 (EDT) Received: from localhost (unknown [127.0.2.5]) by dcvr.yhbt.net (Postfix) with ESMTP id 99CD01F6A9; Wed, 27 Apr 2011 22:32:45 +0000 (UTC) (I'll probably turn this into RDoc and put it on the website somewhere after some editing, comments greatly appreciated as always) Since there's increased interest with streaming responses with Rails 3.1 around the corner and Rainbows! was always designed with streaming responses in mind, I'll suggest things I believe to be useful for use with Rails 3.1 streaming. Rails 3.1 streaming is primarily to reduce latency to clients even with fast responses. You want to be sending data to clients as quickly as possible and buffer as little as possible on the server side. This focuses on Ruby 1.9 since it's required for Rails 3.1 streaming and Linux/NPTL since that's what I have the most experience on. == Thread-safety First off, enable thread-safety in Rails, most options here involve threading in some way and Ruby threading (especially in 1.9.2+) isn't nearly as bad as some people think[1]. == Rainbows! concurrency options === ThreadPool/ThreadSpawn Both of these work pretty well in a standalone configuration (without nginx in front). Your entire app and all its dependencies *must* be thread-safe. === WriterThreadSpawn/WriterThreadPool These /may/ offer more consistent performance if your application (but not rendering) is CPU-intensive as they can better balance requests with multiple cores and more worker_processes. Both of these require nginx in front to be effective against slow client requests. However, nginx users should use "proxy_buffering off" in their nginx config file or "X-Accel-Buffering: no" in their Rack responses to stream responses. This allows parts of the response to get to the client as quickly as possible. All code accessed in your Rails views (helpers, possibly models/controllers) must be thread-safe, but some controller-only code does not require thread-safety. If your middleware wraps responses, those must be thread-safe, too. It might just be as easy to make your entire application thread-safe and worry less later on :) == Hardware/Environment === Memory 64-bit is recommended as you can run more native threads with Ruby 1.9. All you need is addressable (not physical) memory to run more threads with NPTL in Linux. Ruby 1.9.2 requires 512KB of addressable stack per thread, but hopefully 1.9.3 can will have a smaller stack size[3]. Most threads are likely to need <= 64KB of physical stack memory. When choosing hardware, look for a fast memory/bus and large CPU caches. === Context-switching costs I suspect this is negligible compared to the overhead of a high-level language like Ruby in the first place. Feedback/measurements with actual Ruby/Rails application processes/threads would be greatly appreciated. Maybe play around with `schedtool` or `taskset` in Linux if you feel it's a problem. Perhaps pinning all native threads within a process to the same CPU core is the best option to reduce contention for the GVL, but the kernel scheduler may already be smart enough to do that. More analysis is definitely needed in this area.... === worker_connections This is typically the maximum number of threads you'll spawn. worker_connections * worker_processes is the total number of connections you can have on Rainbows! === worker_processes It's safe to increase worker_processes as long as you have *physical* RAM for them. Having more worker_processes will amortize the cost of running GC and increase the amount of work multiple CPUs can do given the GVL. Whatever you do, make sure processes don't get swapped out to disk. More coming later... [1] - if you use any Free/Open Source C extensions[2] that don't work properly with 1.9 native threads, feel welcome to ask for my help publically or privately via email. [2] - I'll only help if the *entire* stack for the extensions is Free/OSS. It cannot be a binding to a non-Free/OSS library which I cannot look at/hack the source for. [3] http://redmine.ruby-lang.org/issues/4614 -- Eric Wong _______________________________________________ Rainbows! mailing list - rainbows-talk-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org http://rubyforge.org/mailman/listinfo/rainbows-talk Do not quote signatures (like this one) or top post when replying