From 2976d3767e6572ee1838b50b5f401983918f99c7 Mon Sep 17 00:00:00 2001 From: Stephen Margheim Date: Thu, 30 May 2024 21:18:46 +0200 Subject: [PATCH] Use the new SQLite3::Database#busy_handler_timeout= method for a non-GVL-blocking, fair retry interval busy handler implementation Co-Authored-By: Jean Boussier --- Gemfile | 2 +- Gemfile.lock | 2 +- activerecord/CHANGELOG.md | 6 ++++++ .../connection_adapters/sqlite3_adapter.rb | 13 ++++++++----- railties/lib/rails/generators/database.rb | 2 +- railties/test/generators/app_generator_test.rb | 2 +- .../generators/db_system_change_generator_test.rb | 2 +- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index d85fc00946c..7546bc43c80 100644 --- a/Gemfile +++ b/Gemfile @@ -153,7 +153,7 @@ platforms :ruby, :windows do gem "nokogiri", ">= 1.8.1", "!= 1.11.0" # Active Record. - gem "sqlite3", ">= 1.6.6" + gem "sqlite3", ">= 2.0" group :db do gem "pg", "~> 1.3" diff --git a/Gemfile.lock b/Gemfile.lock index 83fa39bea68..66bd2e8e118 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -690,7 +690,7 @@ DEPENDENCIES sidekiq sneakers sprockets-rails (>= 2.0.0) - sqlite3 (>= 1.6.6) + sqlite3 (>= 2.0) stackprof stimulus-rails sucker_punch diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 1ba38456a76..0770b76b93b 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +* Replace `SQLite3::Database#busy_timeout` with `#busy_handler_timeout=` + + Provides a non-GVL-blocking, fair retry interval busy handler implementation + + *Stephen Margheim* + * SQLite3Adapter: Translate `SQLite3::BusyException` into `ActiveRecord::StatementTimeout`. *Matthew Nguyen* diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index b3ef60a6aac..ff87b77ff98 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -11,7 +11,7 @@ require "active_record/connection_adapters/sqlite3/schema_definitions" require "active_record/connection_adapters/sqlite3/schema_dumper" require "active_record/connection_adapters/sqlite3/schema_statements" -gem "sqlite3", ">= 1.4" +gem "sqlite3", ">= 2.0" require "sqlite3" module ActiveRecord @@ -783,12 +783,15 @@ module ActiveRecord if @config[:timeout] && @config[:retries] raise ArgumentError, "Cannot specify both timeout and retries arguments" elsif @config[:timeout] - @raw_connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout])) + timeout = self.class.type_cast_config_to_integer(@config[:timeout]) + raise TypeError, "timeout must be integer, not #{timeout}" unless timeout.is_a?(Integer) + @raw_connection.busy_handler_timeout = timeout elsif @config[:retries] + ActiveRecord.deprecator.warn(<<~MSG) + The retries option is deprecated and will be removed in Rails 8.0. Use timeout instead. + MSG retries = self.class.type_cast_config_to_integer(@config[:retries]) - raw_connection.busy_handler do |count| - count <= retries - end + raw_connection.busy_handler { |count| count <= retries } end super diff --git a/railties/lib/rails/generators/database.rb b/railties/lib/rails/generators/database.rb index 838f328382f..e36a0da286e 100644 --- a/railties/lib/rails/generators/database.rb +++ b/railties/lib/rails/generators/database.rb @@ -223,7 +223,7 @@ module Rails end def gem - ["sqlite3", [">= 1.4"]] + ["sqlite3", [">= 2.0"]] end def base_package diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 45ce471a271..9eb16ccd4b5 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -449,7 +449,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_database_is_added_by_default run_generator assert_file "config/database.yml", /sqlite3/ - assert_gem "sqlite3", '">= 1.4"' + assert_gem "sqlite3", '">= 2.0"' end def test_config_mysql_database diff --git a/railties/test/generators/db_system_change_generator_test.rb b/railties/test/generators/db_system_change_generator_test.rb index 1cf442e1685..509d9a1a2ce 100644 --- a/railties/test/generators/db_system_change_generator_test.rb +++ b/railties/test/generators/db_system_change_generator_test.rb @@ -128,7 +128,7 @@ module Rails assert_file("Gemfile") do |content| assert_match "# Use sqlite3 as the database for Active Record", content - assert_match 'gem "sqlite3", ">= 1.4"', content + assert_match 'gem "sqlite3", ">= 2.0"', content end assert_file("Dockerfile") do |content|