NeverBlock: Instant Scaling For Your Rails Apps

Today marks a milestone in the short history of NeverBlock. We have pushed a new release with lots of new features, mainly:

  1. NeverBlock now supports Ruby1.8.
  2. NeverBlock support for Thin and Mongrel servers.
  3. NeverBlock now supports Ruby on Rails.

Let's iterate over the above points and explain them in more detail.

NeverBlock Now Supports Ruby 1.8

Utilizing Aman Gupta's Poor Man's Fibers we were able to add Ruby 1.8 support to NeverBlock. Thankfully this does not mean that applications written for NeverBlock now require full thread safety. Aman's implementation makes sure one thread is scheduled at a time. The fibers don't fight for CPU time so the solution is free of race conditions. The performance penalty is not very big and we were able to extract some very good figures during lab testing.

NeverBlock Support for Thin and Mongrel Servers

Users of Thin or Mongrel servers can now enjoy writing NeverBlock applications that utilize those servers. We are working on adding support to other servers like Flow.

Note: Mongrel support is currently broken. It will be fixed asap.

NeverBlock Now Supports Ruby on Rails

This is the main feature of this release. An end to end seamless support for the Ruby on Rails framework. Adding support for Rails is as easy as modifying a line in your database.yml and adding 2 lines to your environment.rb file. The first of which is:

NeverBlock for Rails currently supports the following configurations:

  1. Thin or Mongrel as an application server To enable NeverBlock for your server put the following line in the environment file you want to enable NeverBlock for. or
  2. PostgreSQL or MySQL as a database server To use the ActiveRecord NeverBlock adapter instead of the stock ones simply add a neverblock_ before the adapter name in database.yml or You can also specify the number of connections you want to spawn by adding: Note: It is preferrable if you have a separate environment for NeverBlock (e.g. neverblock_production) since NeverBlock does not degrade gracefuly (yet) if no server is present. This will cuase your script/console and rake tasks to not function properly. It is better if you have two environments looking at the same database.

You will need to install the required gems before you are able to use NeverBlock with Rails

  1. Download NeverBlock (zip|tar.gz), Mysqlplus (zip|tar.gz), EventMachine (zip|tar.gz)
  2. Uncompress and do the following for each
# build them gem using the .gemspec to obtain the .gem file
gem build (respective file name).gemspec

#install the gem file
gem install (generated file name).gem

One more thing to note is that installing the mysqlplus gem might require having libmysql++-dev. If you're on a debian distribution you can do the following

apt-get install libmysql++-dev

Once the support is added your application will be able to serve requests concurrently by mutliplexing database operations.

We have tested the NeverBlock stack against the old Rails stack using the following configuration:

  1. Rails 2.1
  2. Thin 0.82
  3. Ruby 1.8.6
  4. MySQL 5.0
  5. A special build of EventMachine 0.12

The special EventMachine gem adds a few features to the plain EventMachine. The changes are being merged in the main branch now and should be available in the next EventMachine official release.

We have built a trivial Rails application that would run a slow request every x fast requests. Slow requests are simulated by running a "select sleep(1)" inside the action body while fast requests will issue a "select 1"

Workload was distrivbuted as follows:

1 - Moderate work load,    one slow request for every 050 requests
2 - Heavy work load,       one slow request for every 020 requests
3 - Very heavy work load,  one slow request for every 010 requests

We tested a single NeverBlock::Thin instance against one, four and eight normal Thin instances. We used Apache Bench to benchmark each configuration with 1000 requests and a concurrency level of 200

Here are the results

Rails Performance (Thin Vs.NeverBlock::Thin)

The scaling characteristics under heavy load were benchmarked, we did so with 500 and 1000 concurrent requests.

Thin scaling

NeverBlock::Thin scaling

Memory consumption was recorded for the different configurations

Memory Consumption (Thin Vs. NeverBlock::Thin)

For other benchmarks using Ruby 1.9 and PostgreSQL check here

Comments

1.

very nice!!! maybe put the instructions for the postgresql gem up. I will try this with postgresql when I wake up in the morning. Thanks!!!

5.

@Enog , Thanks for the note , this was a missing file in the gemspec file and we fixed it now..

3.

Whoa! Works out-of-the box now and is super-fast! Haven't really done any serious benchmarking but looking at the tail'd log make feel like I'm in Matrix or something. xD

4.

@Enog Glad it worked for you.... We're having problems with Github not building our gems so the best thing is that you download the gems and build them locally.

5.

@humannzz; Actually I lied, it didn't work. I was just too excited I fooled myself. But I came a lot further than last time.

6.

My configuration: 1. Rails 2.1 2. Thin 0.82 3. Ruby 1.8.5 4. MySQL 6.2 5. A special build of EventMachine 0.12 I have got this error when I install mysqlplus gem Status: 500 Internal Server Error undefined method `collect!' for nil:NilClass /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:582:in `find_by_sql' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1341:in `find_every' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1303:in `find_initial' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:534:in `find' [...] Thanks

7.

i got this: undefined local variable or method `socket' for #

8.

sorry for last post. this is what am getting : undefined local variable or method `socket' for #

9.

@khell: I had that too - uninstall the mysql gem. This one replaces it, from what I've gathered. I'm encountering a different error myself: /usr/local/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/db/fibered_mysql_connection.rb:55:in `register_with_event_loop': REACTOR NOT RUNNING YA ZALAMA (RuntimeError) This is a development box, Fedora Core 6, with EventMachine 0.12.2 (your custom build) running. Any hints?

10.

Well, fixed my problem - I had an ActiveRecord call in my routes.rb (A hack, I know, but a workable one) which causes the Neverblock driver to throw out a hip, since the Thin server hadn't started my EventMachine server yet.

11.

/usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/db/fibered_mysql_connection.rb:23:in `real_connect' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:47:in `connect' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/db/pooled_fibered_mysql_connection.rb:13:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/pool/fibered_connection_pool.rb:47:in `call' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/pool/fibered_connection_pool.rb:47:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/pool/fibered_connection_pool.rb:46:in `times' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/pool/fibered_connection_pool.rb:46:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/db/pooled_fibered_mysql_connection.rb:12:in `new' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block/db/pooled_fibered_mysql_connection.rb:12:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:40:in `new' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:40:in `connect' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/mysql_adapter.rb:183:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:78:in `new' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:78:in `neverblock_mysql_connection' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:292:in `send' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:292:in `connection=' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:260:in `retrieve_connection' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/query_cache.rb:8:in `cache' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/caching/sql_cache.rb:12:in `perform_action' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/base.rb:529:in `send' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/base.rb:529:in `process_without_filters' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/filters.rb:569:in `process_without_session_management_support' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/session_management.rb:130:in `process' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/base.rb:389:in `process' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:149:in `handle_request' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:107:in `dispatch' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:104:in `synchronize' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:104:in `dispatch' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:120:in `dispatch_cgi' /usr/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/dispatcher.rb:35:in `dispatch' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/rack/adapter/rails.rb:54:in `serve_rails' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/rack/adapter/rails.rb:74:in `call' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/connection.rb:59:in `pre_process' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/connection.rb:50:in `process' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/connection.rb:35:in `receive_data' /usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.2/lib/eventmachine.rb:224:in `run_machine' /usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.2/lib/eventmachine.rb:224:in `run' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/backends/base.rb:45:in `start' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/server.rb:146:in `start' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/controllers/controller.rb:79:in `start' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/runner.rb:166:in `send' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/runner.rb:166:in `run_command' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/lib/thin/runner.rb:136:in `run!' /usr/lib/ruby/gems/1.8/gems/thin-0.8.2/bin/thin:6 /usr/bin/thin:19:in `load' /usr/bin/thin:19

12.

@Chris, i have removed the mysql gem and still getting the same odd error....

13.

Well, I've found that my app breaks in a multitude of interesting ways when I replace the mysql gem with mysqlplus. I'm not sure why, but it's breaking everything from find_by_sql ActiveRecord calls to...routing recognition somehow? (I have no idea how, but my routes fail to recognize when running with the mysqlplus rather than mysql gem).

14.

@khell, please make sure you don't have the old mysql.so any where (it may be in /site_ruby). The error you are getting means that mysqlplus is using the old one. @Chris and @vcahv I will look into the find_by_sql issues but I would like to know if the you are both getting the same stack trace, Chris can you verify this?

15.

@Chris, I would like to know more about where your app breaks, and would be glad if you provide a stack trace or a better description of a wrong behavior, thanks

16.

@oldmoe: I'm leaving for a business trip in an hour, but I'll get stack traces and more in-depth problem explanations for you. Is there a better contact method than this comment form that you'd prefer?

17.

For those having troubles with NB and Rails, please add this line to environment.rb require 'never_block/frameworks/rails'

18.

@oldmoe , i could run the app but now am getting undefined method `collect!' for nil:NilClass when doing find_by_sql statments , it's the same problem of Chirs....

19.

Thank you so much for Neverblock... Need to rebuild my server and check it out. Im hoping to get some benchmarks between NB::Thin vs Passanger. As Im about to rebuild a few services with friends.

20.

@Chris, please send to mohammad.ali at espace.com.eg and thanks for going through the trouble

21.

You mentioned "other servers like Flow". Can you explain further? I haven't heard of this.

22.

Is there a status on how this will work on a Windows 1.8 platform?

23.

I have identified the issue with find_by_sql and a fix is being verified. Should be available in a little while

24.

oops, I forgot to thank Chris and Khellls for their help. @generalexception, check here: http://github.com/ry/flow/tree/master @Andy, I will try to provide a compiled gem for windows, but that's not a high priority item at the moment.

25.

New versions of neverblock and mysqlplus were pushed to github. They fix the nil.collect! issue and another issue in transactions

26.

I have another problem with the new build. When I tried to start thin : /usr/lib/ruby/1.8/thread.rb:318:in `stop': Thread(0xb7d58754): deadlock (fatal) from /usr/lib/ruby/1.8/thread.rb:318:in `pop' from /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.3/lib/never_block.rb:27:in `resume'

27.

@vchav, are u requiring 'never_block/frameworks/rails' ? and you should run thin in single threaded mode as well (default)

28.

@oldmoe, yes you are right... I'm sorry :) Can you benchmark with haproxy (maxconn 1 for each thin server) Typical example of configuration : http://purefiction.net/paste/haproxy_vs_nginx/haproxy.cfg (4 thin server) Because I have really better results with it and I want know if it's my fault

29.

yes the app is working now, but we have a problem with utf8 encoding, i get this error : malformed UTF-8 character (expected 2 bytes, given 1 bytes) and only when i remove the mysqlplus gem, i get things to work again.

30.

@khelll, can you send a stack trace?

31.

@all, an update mysqlplus was pushed to github. The data corruption errors should be a bad memory now

32.

Great stuff! Seems to be working smoothly now, and I can't wait to get some benchmarks cranked out! Thanks again for all your hard work!

33.

I am getting RuntimeError: Please install the neverblock_postgresql adapter: `gem install activerecord-neverblock_postgresql-adapter` (no such file to load -- pg) when I try to get neverblock working with thin, postgresql and rails on ruby 1.8.6. I have got neverblock and special eventmachine gem installed. Plus I have added requires in environment.rb and changed database.yml. Do I have to do anything difference for postgresql?

34.

You need to install the pg driver 'sudo gem install pg'

35.

Hi oldmoe, I'm trying this out on my app but it crashes with :http://pastie.org/268773

36.

Well after a bit more investigating I made the following changes: I added: require 'mysqlplus' and commented out my observers so my environment.rb looks like: require 'rubygems' require 'mysqlplus' require 'never_block/frameworks/rails' require 'never_block/servers/mongrel' Rails::Initializer.run do |config| ... # config.active_record.observers = :user_observer end (a slightly old rails edge (2.1.x) => commit: a9259c ) but I'm now getting: http://pastie.org/268830 which I haven't been able to solve yet. Regards, Saimon

37.

@Saimon, please use Thin for now, Mongrel support is broken at the moment. I hope I will be able to get to that soon.

38.

Is passenger support in plans? I've migrated to passenger some time ago and don't want to reconfigure server again :)

39.

oldmoe, yeah I tried thin and it's working but right now I've got my server setup for mongrel so I'll wait until you get that fixed. Not to put any pressure on you :)

40.

@Drogomir, I am not sure if supporting Passenger is possible, we rely on the presence of an event loop which is not the case with Passenger AFAIK

41.

What do you mean by "event loop". Is it server's main loop? Passenger has server implementation written in ruby, maybe you could take a look: http://github.com/FooBarWidget/passenger/tree/master/lib/passenger/abstract_server.rb

42.

First off, this is great, thanks for all of your hard work. If I manage to get it working in my production environment, I'll send a donation your way. (as soon as mongrel support is stable) Second, any plans to implement a neverblock_memcache client? I know memcache requests come back faster, but its still a blocking point. Thanks, Ryan

43.

Wow, this is great news, thanks for improving ruby even further! I would also like to know about passenger support. I won't migrate back to the hell of mongrel/thin. They are good servers, but managing them (especially the port numbers if you have many apps on a server and having a static number of processes per app) just isn't very flexible. Also, what are the differences between using the mysqlplus adapter and neverblock_mysql?

44.

@Drogomir, thanks for the tip, it appears that all we need is to issue a select call within the main loop and introduce the fiber pool. Will look at this when I can spare some time but it looks highly doable. @Ryan, memcached support will be tough as the current API does not provide direct access async APIs. That said, there is a non-block mode for writes which makes writing very fast on memcached at the expense of losing the ability to get a feedback @Mathijs, Passenger support is an interesting possibility. Regarding MysqlPlus and neverblock-mysql the difference is that MysqlPlus is a general purpose Mysql driver with async feautres, nb-mysql is wrapper that provide hooks for integration with other NeverBlock components

45.

@oldmoe, so I should use mysqlplus until neverblock supports passenger, then switch to nb-mysql?

46.

@Mathijs, whenever NB supports Passenger you will only need to use the neverblock_mysql adapter in database.yml, until then the mysqlplus driver will only help you with multi-threaded Rails (that's 2.2)

47.

@oldmoe: Hmm... let me understand it :) Does your above post mean, that if I use passenger with rails 2.2 (or rails edge at the moment) and neverblock_postgres adapter I will profit from it, since edge rails is thread safe now? Sorry if this is dumb question, but I think I can't understand how exactly neverblock works with mongrel/thin and rails :)

48.

Hi guys, my environment: linux, ruby 1.8, rails 2.1, thin, mysql i've downloaded and installed all needed gems. my environment.rb file starts with require 'mysqlplus' require 'never_block/frameworks/rails' require 'never_block/servers/thin' and i got this error: You have a nil object when you didn't expect it! The error occurred while evaluating nil.fileno /usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.2/lib/eventmachine.rb:754:in `attach' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/db/fibered_mysql_connection.rb:74:in `register_with_event_loop' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:54:in `connect' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/db/pooled_fibered_mysql_connection.rb:13:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/pool/fibered_connection_pool.rb:47:in `call' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/pool/fibered_connection_pool.rb:47:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/pool/fibered_connection_pool.rb:46:in `times' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/pool/fibered_connection_pool.rb:46:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/db/pooled_fibered_mysql_connection.rb:12:in `new' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/never_block/db/pooled_fibered_mysql_connection.rb:12:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:40:in `new' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:40:in `connect' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/mysql_adapter.rb:183:in `initialize' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:78:in `new' /usr/lib/ruby/gems/1.8/gems/neverblock-0.1.4/lib/active_record/connection_adapters/neverblock_mysql_adapter.rb:78:in `neverblock_mysql_connection' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:292:in `send' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:292:in `connection=' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:260:in `retrieve_connection' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1145:in `columns' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1158:in `column_names' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1171:in `column_methods_hash' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1714:in `all_attributes_exists?' /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/inflector.rb:283:in `all?' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1714:in `each' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1714:in `all?' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1714:in `all_attributes_exists?' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1613:in `method_missing' /home/alex/work/harvester/trunk/sources/tracker/app/controllers/application.rb:12:in `authorize' /usr/bin/thin:19:in `load' /usr/bin/thin:19 Any hints?

49.

@Drogomir, to make a long story short, what neverblock does is that it hooks with the thin server, wraps requests in neverblock fibers. Now when a request is waiting for DB IO it is paused and another request could be started and so on. Unless your server is modified to work with NeverBlock then you will not benefit from the neverblock adapter

50.

@alex, we are working on a new release which should be much more robust. This error (and others) should be fixed in it. Expect it soon

51.

Same as alex, and wish for the next patch. Good work man, really exciting about it! :D

52.

Thanks, waiting for new release

54.

I tried to run one of my rails apps with neverblock_postgresql to check performance boost and I've run into problems... could you look at backtrace? http://pastie.org/278475 I tried to add NB=NeverBlock, but then some other const missing errors appeared.

54.

/home/jorge/Projects/Neris/neris/vendor/rails/activesupport/lib/active_support/dependencies.rb:493:in `const_missing': uninitialized constant CGI::Session::ActiveRecordStore (NameError)

55.

I'm probably reading the graphs wrong, but if you have a just fast requests or not very many requests will NeverBlock actually make things run slower? Does NeverBlock only speed things up under very heavy load, and do individual requests run any slower if their is very light load? I'm just trying to figure out when it would be best to use NeverBlock. It seems like it could be worse in some cases, but (obviously) much better in others. Thanks so much for the hard work!