Permalink
Browse files

Database connections are now pooled, one pool per #establish_connecti…

…on call.

Pools start out empty and grow as necessary to a maximum size (default is 5,
configure size with key 'pool' in your database configuration). If no
connections are available, a thread will wait up to a 'wait_timeout' time
(default is 5 seconds).

Connections are verified and reset when checked out from the pool (usually
upon first access to ActiveRecord::Base.connection), and returned back to the
pool after each request.

If you would like to use connection pools outside of ActionPack, there is an
ActiveRecord::Base.connection_pool method that gives you access to the pool,
and you can manually checkout/checkin connections, or supply a block to
ActiveRecord::Base.connection_pool.with_connection which takes care of the
checkout/checkin for you.

[#936 state:resolved]
  • Loading branch information...
jeremy committed Sep 2, 2008
2 parents 3007545 + ebfa43c commit 6f932b4790371e548c0df9033da96b2cf8f51dcc
Showing with 1,175 additions and 708 deletions.
  1. +0 −24 README.rdoc
  2. +5 −0 actionmailer/CHANGELOG
  3. +38 −7 actionmailer/lib/action_mailer/base.rb
  4. +2 −2 actionmailer/lib/action_mailer/helpers.rb
  5. +1 −0 actionmailer/test/fixtures/auto_layout_mailer/hello.html.erb
  6. +1 −0 actionmailer/test/fixtures/explicit_layout_mailer/logout.html.erb
  7. +1 −0 actionmailer/test/fixtures/explicit_layout_mailer/signup.html.erb
  8. +1 −0 actionmailer/test/fixtures/layouts/auto_layout_mailer.html.erb
  9. +1 −0 actionmailer/test/fixtures/layouts/spam.html.erb
  10. +78 −0 actionmailer/test/mail_layout_test.rb
  11. +52 −0 actionmailer/test/mail_service_test.rb
  12. +16 −0 actionpack/CHANGELOG
  13. +26 −52 actionpack/lib/action_controller/assertions/selector_assertions.rb
  14. +25 −63 actionpack/lib/action_controller/base.rb
  15. +2 −2 actionpack/lib/action_controller/caching/actions.rb
  16. +3 −3 actionpack/lib/action_controller/caching/sweeping.rb
  17. +3 −3 actionpack/lib/action_controller/cgi_process.rb
  18. +1 −1 actionpack/lib/action_controller/components.rb
  19. +4 −4 actionpack/lib/action_controller/filters.rb
  20. +2 −2 actionpack/lib/action_controller/helpers.rb
  21. +1 −1 actionpack/lib/action_controller/http_authentication.rb
  22. +4 −4 actionpack/lib/action_controller/integration.rb
  23. +21 −47 actionpack/lib/action_controller/layout.rb
  24. +3 −3 actionpack/lib/action_controller/polymorphic_routes.rb
  25. +0 −3 actionpack/lib/action_controller/rescue.rb
  26. +61 −12 actionpack/lib/action_controller/resources.rb
  27. +3 −2 actionpack/lib/action_controller/routing/optimisations.rb
  28. +3 −3 actionpack/lib/action_controller/routing/route_set.rb
  29. +12 −5 actionpack/lib/action_controller/test_process.rb
  30. +2 −2 actionpack/lib/action_controller/verification.rb
  31. +94 −76 actionpack/lib/action_view/base.rb
  32. +9 −1 actionpack/lib/action_view/helpers/prototype_helper.rb
  33. +1 −1 actionpack/lib/action_view/partials.rb
  34. +4 −4 actionpack/lib/action_view/renderable.rb
  35. +1 −1 actionpack/lib/action_view/template_handlers/builder.rb
  36. +1 −1 actionpack/lib/action_view/test_case.rb
  37. +5 −0 actionpack/test/controller/assert_select_test.rb
  38. +4 −4 actionpack/test/controller/base_test.rb
  39. +2 −2 actionpack/test/controller/filter_params_test.rb
  40. +13 −13 actionpack/test/controller/filters_test.rb
  41. +1 −1 actionpack/test/controller/integration_test.rb
  42. +0 −49 actionpack/test/controller/layout_test.rb
  43. +43 −0 actionpack/test/controller/render_test.rb
  44. +109 −25 actionpack/test/controller/resources_test.rb
  45. +6 −0 actionpack/test/controller/routing_test.rb
  46. +15 −0 actionpack/test/template/prototype_helper_test.rb
  47. +1 −1 activemodel/lib/active_model/validations.rb
  48. +2 −0 activerecord/CHANGELOG
  49. +5 −1 activerecord/lib/active_record/associations.rb
  50. +6 −2 activerecord/lib/active_record/named_scope.rb
  51. +2 −1 activerecord/lib/active_record/validations.rb
  52. +25 −9 activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
  53. +23 −7 activerecord/test/cases/associations/has_many_associations_test.rb
  54. +20 −0 activerecord/test/cases/associations/has_many_through_associations_test.rb
  55. +15 −0 activerecord/test/cases/named_scope_test.rb
  56. +33 −0 activerecord/test/cases/validations_i18n_test.rb
  57. +10 −5 activeresource/lib/active_resource/base.rb
  58. +18 −7 activeresource/lib/active_resource/connection.rb
  59. +12 −11 activeresource/lib/active_resource/custom_methods.rb
  60. +6 −6 activeresource/lib/active_resource/formats/json_format.rb
  61. +9 −9 activeresource/lib/active_resource/formats/xml_format.rb
  62. +1 −1 activeresource/lib/active_resource/http_mock.rb
  63. +8 −8 activeresource/test/authorization_test.rb
  64. +1 −2 activeresource/test/base/custom_methods_test.rb
  65. +2 −2 activeresource/test/base/load_test.rb
  66. +5 −5 activeresource/test/base_test.rb
  67. +1 −1 activeresource/test/connection_test.rb
  68. +23 −11 activeresource/test/format_test.rb
  69. +10 −1 activesupport/lib/active_support/core_ext/module.rb
  70. +71 −67 activesupport/lib/active_support/core_ext/module/aliasing.rb
  71. +79 −75 activesupport/lib/active_support/core_ext/module/introspection.rb
  72. +5 −5 activesupport/lib/active_support/core_ext/module/model_naming.rb
  73. +0 −5 activesupport/lib/active_support/core_ext/object/misc.rb
  74. +35 −0 activesupport/lib/active_support/core_ext/rexml.rb
  75. +1 −1 activesupport/lib/active_support/core_ext/time/zones.rb
  76. +1 −1 activesupport/lib/active_support/option_merger.rb
  77. +5 −1 activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb
  78. +1 −1 activesupport/lib/active_support/time_with_zone.rb
  79. +20 −17 activesupport/lib/active_support/vendor/i18n-0.0.1/i18n/backend/simple.rb
  80. +2 −1 activesupport/test/buffered_logger_test.rb
  81. +25 −4 activesupport/test/core_ext/hash_ext_test.rb
  82. +0 −5 activesupport/test/core_ext/object_and_class_ext_test.rb
  83. +9 −9 activesupport/test/dependencies_test.rb
  84. +1 −1 railties/lib/initializer.rb
  85. +2 −2 railties/lib/tasks/documentation.rake
View
@@ -1,24 +0,0 @@
== About
This is Nick's connection pool branch, wherein he attempts to rewrite Rails' connection handling code to
be more thread-safe, and to add connection pooling features.
== Goals
- Preserve Rails' lazy connection acquisition and caching strategy behavior as it exists prior to this work.
- Add ability to configure a connection pool to limit the number of connections made to a database in multiple-thread scenarios.
- Threads will block for a configurable timeout if the pool is exhausted until a connection is available.
- If none is available during the timeout period, an exception will be raised.
- Add a checkout/checkin API to reserve and release a connection to/from the pool.
- Add several different connection handling/pooling classes to serve different needs:
- proper fixed-size connection pool
- connection-per-thread with no maximum on the number of connections
- single thread cached connection
- pass-through to external connection pool (JRuby/JNDI data source connection pool)
== TODO
Remaining tasks:
- Review and put the thing to real work.
- Look at whether existing clear_* or verify_* methods can be deprecated or removed.
View
@@ -1,3 +1,8 @@
* Add layout functionality to mailers [Pratik]
Mailer layouts behaves just like controller layouts, except layout names need to
have '_mailer' postfix for them to be automatically picked up.
*2.1.0 (May 31st, 2008)*
* Fixed that a return-path header would be ignored #7572 [joost]
@@ -246,7 +246,10 @@ module ActionMailer #:nodoc:
# +implicit_parts_order+.
class Base
include AdvAttrAccessor, PartContainer
include ActionController::UrlWriter if Object.const_defined?(:ActionController)
if Object.const_defined?(:ActionController)
include ActionController::UrlWriter
include ActionController::Layout
end
private_class_method :new #:nodoc:
@@ -362,6 +365,7 @@ def mailer_name=(value)
# The mail object instance referenced by this mailer.
attr_reader :mail
attr_reader :template_name, :default_template_name, :action_name
class << self
attr_writer :mailer_name
@@ -374,11 +378,16 @@ def mailer_name
alias_method :controller_name, :mailer_name
alias_method :controller_path, :mailer_name
def method_missing(method_symbol, *parameters)#:nodoc:
case method_symbol.id2name
when /^create_([_a-z]\w*)/ then new($1, *parameters).mail
when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver!
when "new" then nil
def respond_to?(method_symbol, include_private = false) #:nodoc:
matches_dynamic_method?(method_symbol) || super
end
def method_missing(method_symbol, *parameters) #:nodoc:
match = matches_dynamic_method?(method_symbol)
case match[1]
when 'create' then new(match[2], *parameters).mail
when 'deliver' then new(match[2], *parameters).deliver!
when 'new' then nil
else super
end
end
@@ -424,6 +433,12 @@ def template_root
def template_root=(root)
self.view_paths = ActionView::Base.process_view_paths(root)
end
private
def matches_dynamic_method?(method_name) #:nodoc:
method_name = method_name.to_s
/(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name)
end
end
# Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
@@ -519,6 +534,7 @@ def initialize_defaults(method_name)
@content_type ||= @@default_content_type.dup
@implicit_parts_order ||= @@default_implicit_parts_order.dup
@template ||= method_name
@default_template_name = @action_name = @template
@mailer_name ||= self.class.name.underscore
@parts ||= []
@headers ||= {}
@@ -535,7 +551,22 @@ def render(opts)
if opts[:file] && (opts[:file] !~ /\// && !opts[:file].respond_to?(:render))
opts[:file] = "#{mailer_name}/#{opts[:file]}"
end
initialize_template_class(body).render(opts)
begin
old_template, @template = @template, initialize_template_class(body)
layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
@template.render(opts.merge(:layout => layout))
ensure
@template = old_template
end
end
def default_template_format
:html
end
def candidate_for_layout?(options)
!@template.send(:_exempt_from_layout?, default_template_name)
end
def template_root
@@ -72,7 +72,7 @@ def helper_method(*methods)
methods.flatten.each do |method|
master_helper_module.module_eval <<-end_eval
def #{method}(*args, &block)
controller.send!(%(#{method}), *args, &block)
controller.__send__(%(#{method}), *args, &block)
end
end_eval
end
@@ -92,7 +92,7 @@ def inherited_with_helper(child)
inherited_without_helper(child)
begin
child.master_helper_module = Module.new
child.master_helper_module.send! :include, master_helper_module
child.master_helper_module.__send__(:include, master_helper_module)
child.helper child.name.to_s.underscore
rescue MissingSourceFile => e
raise unless e.is_missing?("helpers/#{child.name.to_s.underscore}_helper")
@@ -0,0 +1 @@
You logged out
@@ -0,0 +1 @@
We do not spam
@@ -0,0 +1 @@
Hello from layout <%= yield %>
@@ -0,0 +1 @@
Spammer layout <%= yield %>
@@ -0,0 +1,78 @@
require 'abstract_unit'
class AutoLayoutMailer < ActionMailer::Base
def hello(recipient)
recipients recipient
subject "You have a mail"
from "tester@example.com"
end
def spam(recipient)
recipients recipient
subject "You have a mail"
from "tester@example.com"
body render(:inline => "Hello, <%= @world %>", :layout => 'spam', :body => { :world => "Earth" })
end
def nolayout(recipient)
recipients recipient
subject "You have a mail"
from "tester@example.com"
body render(:inline => "Hello, <%= @world %>", :layout => false, :body => { :world => "Earth" })
end
end
class ExplicitLayoutMailer < ActionMailer::Base
layout 'spam', :except => [:logout]
def signup(recipient)
recipients recipient
subject "You have a mail"
from "tester@example.com"
end
def logout(recipient)
recipients recipient
subject "You have a mail"
from "tester@example.com"
end
end
class LayoutMailerTest < Test::Unit::TestCase
def setup
set_delivery_method :test
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries = []
@recipient = 'test@localhost'
end
def teardown
restore_delivery_method
end
def test_should_pickup_default_layout
mail = AutoLayoutMailer.create_hello(@recipient)
assert_equal "Hello from layout Inside", mail.body.strip
end
def test_should_pickup_layout_given_to_render
mail = AutoLayoutMailer.create_spam(@recipient)
assert_equal "Spammer layout Hello, Earth", mail.body.strip
end
def test_should_respect_layout_false
mail = AutoLayoutMailer.create_nolayout(@recipient)
assert_equal "Hello, Earth", mail.body.strip
end
def test_explicit_class_layout
mail = ExplicitLayoutMailer.create_signup(@recipient)
assert_equal "Spammer layout We do not spam", mail.body.strip
end
def test_explicit_layout_exceptions
mail = ExplicitLayoutMailer.create_logout(@recipient)
assert_equal "You logged out", mail.body.strip
end
end
@@ -968,3 +968,55 @@ def test_send_method
end
end
end
class RespondToTest < Test::Unit::TestCase
class RespondToMailer < ActionMailer::Base; end
def setup
set_delivery_method :test
end
def teardown
restore_delivery_method
end
def test_should_respond_to_new
assert RespondToMailer.respond_to?(:new)
end
def test_should_respond_to_create_with_template_suffix
assert RespondToMailer.respond_to?(:create_any_old_template)
end
def test_should_respond_to_deliver_with_template_suffix
assert RespondToMailer.respond_to?(:deliver_any_old_template)
end
def test_should_not_respond_to_new_with_template_suffix
assert !RespondToMailer.respond_to?(:new_any_old_template)
end
def test_should_not_respond_to_create_with_template_suffix_unless_it_is_separated_by_an_underscore
assert !RespondToMailer.respond_to?(:createany_old_template)
end
def test_should_not_respond_to_deliver_with_template_suffix_unless_it_is_separated_by_an_underscore
assert !RespondToMailer.respond_to?(:deliverany_old_template)
end
def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_uppercase_letter
assert !RespondToMailer.respond_to?(:create_Any_old_template)
end
def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_uppercase_letter
assert !RespondToMailer.respond_to?(:deliver_Any_old_template)
end
def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_digit
assert !RespondToMailer.respond_to?(:create_1_template)
end
def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_digit
assert !RespondToMailer.respond_to?(:deliver_1_template)
end
end
View
@@ -1,5 +1,21 @@
*Edge*
* Add support for shallow nesting of routes. #838 [S. Brent Faulkner]
Example :
map.resources :users, :shallow => true do |user|
user.resources :posts
end
- GET /users/1/posts (maps to PostsController#index action as usual)
named route "user_posts" is added as usual.
- GET /posts/2 (maps to PostsController#show action as if it were not nested)
Additionally, named route "post" is added too.
* Added button_to_remote helper. #3641 [Donald Piret, Tarmo Tänav]
* Deprecate render_component. Please use render_component plugin from http://github.com/rails/render_component/tree/master [Pratik]
* Routes may be restricted to lists of HTTP methods instead of a single method or :any. #407 [Brennan Dunn, Gaius Centus Novus]
Oops, something went wrong.

0 comments on commit 6f932b4

Please sign in to comment.