activerecord-dynamic_timeout 0.0.1.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0f13bd79fe5a35f5979b91ec7f702ad0fe0d95ff743a2a91dc3a81a9c8e78fa7
4
+ data.tar.gz: d1c6f748961cb9c812215f2ee710fc88f99d7230a67986710152ecda8bb8f811
5
+ SHA512:
6
+ metadata.gz: 57286088e5d8fdb64d24e24e949dce507ff8afb10d295182c42926df5eef6fa2c4d1abc5e3a55812596b32d56969f8b9ad2b0eadbd6c7fc1443b973a6109c32b
7
+ data.tar.gz: 24e3f13a1c85ab0efd0d68222fe9b8e2fd4e1a84816c01fe28b00736e386c33a6d70ed94ae6261ecb57400a644d24a2e9415c89c55e4d851945ccfe94c417e6b
data/Appraisals ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "appraisal/matrix"
4
+
5
+ appraisal_matrix(activerecord: "6.1") do |activerecord:|
6
+ if activerecord < "7.2"
7
+ gem "sqlite3", "~> 1.4"
8
+ end
9
+ end
10
+ # appraisal_matrix(activerecord: "6.1", mysql2: { versions: ["~> 0.5"], step: :major })
11
+ # appraisal_matrix(activerecord: "6.1", pg: { versions: ["~> 1.5"], step: :major })
12
+ #
13
+ # appraisal_matrix(activerecord: [">= 6.1", "< 7.2"], sqlite3: { versions: ["~> 1.4"], step: :major })
14
+ # appraisal_matrix(activerecord: "7.2", sqlite3: { versions: [">= 1.4"], step: :major })
15
+ # appraisal_matrix(activerecord: "7.1", trilogy: { versions: [">= 2.8"], step: :major })
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "appraisal"
6
+ gem "appraisal-matrix"
7
+ gem "debug"
8
+ gem "mysql2"
9
+ gem "pg"
10
+ gem "rspec"
11
+ gem "sqlite3"
12
+ gem "trilogy"
data/Gemfile.lock ADDED
@@ -0,0 +1,96 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ activerecord-dynamic_timeout (0.0.1.rc1)
5
+ activerecord (>= 6.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (7.2.1)
11
+ activesupport (= 7.2.1)
12
+ activerecord (7.2.1)
13
+ activemodel (= 7.2.1)
14
+ activesupport (= 7.2.1)
15
+ timeout (>= 0.4.0)
16
+ activesupport (7.2.1)
17
+ base64
18
+ bigdecimal
19
+ concurrent-ruby (~> 1.0, >= 1.3.1)
20
+ connection_pool (>= 2.2.5)
21
+ drb
22
+ i18n (>= 1.6, < 2)
23
+ logger (>= 1.4.2)
24
+ minitest (>= 5.1)
25
+ securerandom (>= 0.3)
26
+ tzinfo (~> 2.0, >= 2.0.5)
27
+ appraisal (2.5.0)
28
+ bundler
29
+ rake
30
+ thor (>= 0.14.0)
31
+ appraisal-matrix (0.3.0)
32
+ appraisal (~> 2.2)
33
+ base64 (0.2.0)
34
+ bigdecimal (3.1.8)
35
+ concurrent-ruby (1.3.4)
36
+ connection_pool (2.4.1)
37
+ debug (1.9.2)
38
+ irb (~> 1.10)
39
+ reline (>= 0.3.8)
40
+ diff-lcs (1.5.1)
41
+ drb (2.2.1)
42
+ i18n (1.14.6)
43
+ concurrent-ruby (~> 1.0)
44
+ io-console (0.7.2)
45
+ irb (1.14.0)
46
+ rdoc (>= 4.0.0)
47
+ reline (>= 0.4.2)
48
+ logger (1.6.1)
49
+ minitest (5.25.1)
50
+ mysql2 (0.5.6)
51
+ pg (1.5.8)
52
+ psych (5.1.2)
53
+ stringio
54
+ rake (13.2.1)
55
+ rdoc (6.7.0)
56
+ psych (>= 4.0.0)
57
+ reline (0.5.10)
58
+ io-console (~> 0.5)
59
+ rspec (3.13.0)
60
+ rspec-core (~> 3.13.0)
61
+ rspec-expectations (~> 3.13.0)
62
+ rspec-mocks (~> 3.13.0)
63
+ rspec-core (3.13.1)
64
+ rspec-support (~> 3.13.0)
65
+ rspec-expectations (3.13.3)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.13.0)
68
+ rspec-mocks (3.13.1)
69
+ diff-lcs (>= 1.2.0, < 2.0)
70
+ rspec-support (~> 3.13.0)
71
+ rspec-support (3.13.1)
72
+ securerandom (0.3.1)
73
+ sqlite3 (2.0.4-arm64-darwin)
74
+ stringio (3.1.1)
75
+ thor (1.3.2)
76
+ timeout (0.4.1)
77
+ trilogy (2.8.1)
78
+ tzinfo (2.0.6)
79
+ concurrent-ruby (~> 1.0)
80
+
81
+ PLATFORMS
82
+ arm64-darwin
83
+
84
+ DEPENDENCIES
85
+ activerecord-dynamic_timeout!
86
+ appraisal
87
+ appraisal-matrix
88
+ debug
89
+ mysql2
90
+ pg
91
+ rspec
92
+ sqlite3
93
+ trilogy
94
+
95
+ BUNDLED WITH
96
+ 2.5.5
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT LICENSE
2
+
3
+ Copyright (c) 2024 Tristan Starck <tstarck@invoca.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # activerecord-dynamic_timeout
2
+ Dynamic Timeouts within ActiveRecord
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ Bundler::GemHelper.install_tasks
2
+
3
+ task default: :rspec
4
+
5
+ desc "run rspec unit tests"
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:rspec)
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path("../lib", __FILE__)
4
+ require "active_record/dynamic_timeout/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "activerecord-dynamic_timeout"
8
+ s.version = ActiveRecord::DynamicTimeout::VERSION
9
+ s.authors = ["Tristan Starck"]
10
+ s.email = ["tstarck@invoca.com", "Invoca Development"]
11
+ s.homepage = "https://github.com/Invoca/activerecord-dynamic_timeout"
12
+ s.licenses = ["MIT"]
13
+ s.summary = "ActiveRecord extension for dynamically setting connection timeouts"
14
+ s.description = s.summary
15
+ s.metadata = {
16
+ "allowed_push_host" => "https://rubygems.org",
17
+ "source_code_uri" => s.homepage,
18
+ }
19
+
20
+ s.files = Dir.glob("{bin/*,lib/**/*,[A-Z]*}")
21
+ s.platform = Gem::Platform::RUBY
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency "activerecord", ">= 6.1"
25
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/concern"
5
+ require_relative "../../dynamic_timeout"
6
+
7
+ module ActiveRecord::DynamicTimeout
8
+ module AbstractAdapterExtension
9
+ extend ActiveSupport::Concern
10
+
11
+ attr_accessor :active_record_dynamic_timeout
12
+
13
+ included do
14
+ set_callback :checkin, :before, :reset_dynamic_timeout_for_checkin, prepend: true
15
+ end
16
+
17
+ def supports_dynamic_timeouts?
18
+ false
19
+ end
20
+
21
+ def set_dynamic_timeout(raw_connection, timeout)
22
+ return unless supports_dynamic_timeouts?
23
+ return if active_record_dynamic_timeout == timeout
24
+ if timeout.nil?
25
+ reset_dynamic_timeout(raw_connection)
26
+ else
27
+ set_connection_timeout(raw_connection, timeout)
28
+ self.active_record_dynamic_timeout = timeout
29
+ end
30
+ end
31
+
32
+ def reset_dynamic_timeout(raw_connection)
33
+ return unless supports_dynamic_timeouts?
34
+ return if active_record_dynamic_timeout.nil?
35
+ reset_connection_timeout(raw_connection)
36
+ self.active_record_dynamic_timeout = nil
37
+ end
38
+ end
39
+
40
+ module TimeoutAdapterExtension
41
+ def with_raw_connection(*args, **kwargs, &block)
42
+ super do |raw_connection|
43
+ set_dynamic_timeout(raw_connection, ActiveRecord::Base.current_timeout)
44
+ yield raw_connection
45
+ ensure
46
+ if timeout_set_client_side?
47
+ reset_dynamic_timeout(raw_connection)
48
+ end
49
+ end
50
+ end
51
+
52
+ # This ensures new connections from reconnects have the correct timeout.
53
+ def configure_connection
54
+ super
55
+ if active_record_dynamic_timeout && !timeout_set_client_side?
56
+ set_connection_timeout(@raw_connection, active_record_dynamic_timeout)
57
+ end
58
+ end
59
+
60
+ def reset_dynamic_timeout_for_checkin
61
+ if active_record_dynamic_timeout
62
+ with_raw_connection do |conn|
63
+ reset_dynamic_timeout(conn)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ module TimeoutAdapterExtension_Rails_7_0
70
+ def log(*args, **kwargs, &block)
71
+ super do
72
+ set_dynamic_timeout(@connection, ActiveRecord::Base.current_timeout)
73
+ yield
74
+ ensure
75
+ if timeout_set_client_side?
76
+ reset_dynamic_timeout(@connection)
77
+ end
78
+ end
79
+ end
80
+
81
+ # This ensures new connections from reconnects have the correct timeout.
82
+ def configure_connection
83
+ super
84
+ if active_record_dynamic_timeout && !timeout_set_client_side?
85
+ set_connection_timeout(@connection, active_record_dynamic_timeout)
86
+ end
87
+ end
88
+
89
+ def reset_dynamic_timeout_for_checkin
90
+ if @connection
91
+ reset_dynamic_timeout(@connection)
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/concern"
5
+
6
+ module ActiveRecord::DynamicTimeout
7
+ module BaseExtension
8
+ extend ActiveSupport::Concern
9
+
10
+ module ClassMethods
11
+ def with_timeout(timeout)
12
+ (timeout.is_a?(Integer) || timeout.nil?) or raise ArgumentError, "timeout must be an Integer or NilClass, got: `#{timeout.inspect}`"
13
+ timeout_stack << timeout
14
+ yield
15
+ ensure
16
+ timeout_stack.pop
17
+ end
18
+
19
+ def current_timeout
20
+ timeout_stack.last
21
+ end
22
+
23
+ # @param [Class] scope_class
24
+ def timeout_isolation_scope=(scope_class)
25
+ (scope_class == Thread || scope_class == Fiber) or raise ArgumentError, "scope must be `Thread` or `Fiber`, got: `#{scope_class.inspect}`"
26
+ raise ArgumentError, "timeout_isolation_scope can only be set once" if @timeout_isolation_scope
27
+ @timeout_isolation_scope = scope_class
28
+ end
29
+
30
+ private
31
+
32
+ def timeout_stack
33
+ if (stack = timeout_isolation_state[:active_record_dynamic_timeout_stack])
34
+ stack
35
+ else
36
+ stack = []
37
+ timeout_isolation_state[:active_record_dynamic_timeout_stack] = stack
38
+ stack
39
+ end
40
+ end
41
+
42
+ def timeout_isolation_state
43
+ if timeout_isolation_scope == Thread
44
+ Thread.current.thread_variable_get(:ar_dynamic_timeout_execution_state) ||
45
+ Thread.current.thread_variable_set(:ar_dynamic_timeout_execution_state, {})
46
+ else
47
+ # Thread.current[] is Fiber local
48
+ Thread.current[:ar_dynamic_timeout_execution_state] ||= {}
49
+ end
50
+ end
51
+
52
+ def timeout_isolation_scope
53
+ @timeout_isolation_scope
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveRecord::DynamicTimeout
2
+ module Mysql2AdapterExtension
3
+ def set_connection_timeout(raw_connection, timeout)
4
+ set_timeouts_on_connection(raw_connection, read_timeout: timeout, write_timeout: timeout)
5
+ end
6
+
7
+ def reset_connection_timeout(raw_connection)
8
+ read_timeout = Integer(@config[:read_timeout]) unless @config[:read_timeout].nil?
9
+ write_timeout = Integer(@config[:write_timeout]) unless @config[:write_timeout].nil?
10
+ set_timeouts_on_connection(raw_connection, read_timeout:, write_timeout:)
11
+ end
12
+
13
+ def timeout_set_client_side?
14
+ true
15
+ end
16
+
17
+ def supports_dynamic_timeouts?
18
+ true
19
+ end
20
+
21
+ private
22
+
23
+ def set_timeouts_on_connection(raw_connection, read_timeout:, write_timeout:)
24
+ raw_connection.instance_variable_set(:@read_timeout, read_timeout)
25
+ raw_connection.instance_variable_set(:@write_timeout, write_timeout)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ module ActiveRecord::DynamicTimeout
2
+ module PostgresAdapterExtension
3
+ def set_connection_timeout(raw_connection, timeout)
4
+ if timeout.nil? || timeout == ":default" || timeout == :default
5
+ raw_connection.query("SET SESSION statement_timeout TO DEFAULT")
6
+ else
7
+ raw_connection.query("SET SESSION statement_timeout TO #{quote(timeout)}")
8
+ end
9
+ end
10
+
11
+ def reset_connection_timeout(raw_connection)
12
+ set_connection_timeout(raw_connection, default_statement_timeout)
13
+ end
14
+
15
+ def timeout_set_client_side?
16
+ false
17
+ end
18
+
19
+ def supports_dynamic_timeouts?
20
+ true
21
+ end
22
+
23
+ private
24
+
25
+ def default_statement_timeout
26
+ unless defined?(@default_statement_timeout)
27
+ @default_statement_timeout = @config.fetch(:variables, {}).stringify_keys["statement_timeout"]
28
+ end
29
+ @default_statement_timeout
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord::DynamicTimeout
4
+ module SqliteAdapterExtension
5
+ def set_connection_timeout(raw_connection, timeout)
6
+ if timeout
7
+ raw_connection.busy_timeout(timeout)
8
+ else
9
+ raw_connection.busy_timeout(0)
10
+ end
11
+ end
12
+
13
+ def reset_connection_timeout(raw_connection)
14
+ timeout = @config[:timeout]
15
+ set_connection_timeout(raw_connection, self.class.type_cast_config_to_integer(timeout))
16
+ end
17
+
18
+ def timeout_set_client_side?
19
+ false
20
+ end
21
+
22
+ def supports_dynamic_timeouts?
23
+ true
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveRecord::DynamicTimeout
2
+ module TrilogyAdapterExtension
3
+ def set_connection_timeout(raw_connection, timeout)
4
+ set_timeouts_on_connection(raw_connection, read_timeout: timeout, write_timeout: timeout)
5
+ end
6
+
7
+ def reset_connection_timeout(raw_connection)
8
+ read_timeout = @config[:read_timeout]
9
+ write_timeout = @config[:write_timeout]
10
+ set_timeouts_on_connection(raw_connection, read_timeout:, write_timeout:)
11
+ end
12
+
13
+ def timeout_set_client_side?
14
+ true
15
+ end
16
+
17
+ def supports_dynamic_timeouts?
18
+ true
19
+ end
20
+
21
+ private
22
+
23
+ def set_timeouts_on_connection(raw_connection, read_timeout:, write_timeout:)
24
+ raw_connection.read_timeout = read_timeout
25
+ raw_connection.write_timeout = write_timeout
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "active_support"
5
+ require_relative "../dynamic_timeout"
6
+ require_relative "extensions/base_extension"
7
+ require_relative "extensions/abstract_adapter_extension"
8
+ require_relative "extensions/mysql2_adapter_extension"
9
+ require_relative "extensions/trilogy_adapter_extension"
10
+ require_relative "extensions/sqlite_adapter_extension"
11
+ require_relative "extensions/postgres_adapter_extension"
12
+
13
+ module ActiveRecord::DynamicTimeout
14
+ module Initializer
15
+ class << self
16
+ def initialize!
17
+ ActiveRecord::Base.include(ActiveRecord::DynamicTimeout::BaseExtension)
18
+ ActiveRecord::Base.connection.class.include(ActiveRecord::DynamicTimeout::AbstractAdapterExtension)
19
+
20
+ if ActiveRecord.gem_version < "7.1"
21
+ ActiveRecord::Base.connection.class.prepend(ActiveRecord::DynamicTimeout::TimeoutAdapterExtension_Rails_7_0)
22
+ else
23
+ ActiveRecord::Base.connection.class.prepend(ActiveRecord::DynamicTimeout::TimeoutAdapterExtension)
24
+ end
25
+ register_adapter_extension(ActiveRecord::Base.connection.class)
26
+ end
27
+
28
+ def register_adapter_extension(adapter_class)
29
+ extension = case adapter_class.name
30
+ when "ActiveRecord::ConnectionAdapters::Mysql2Adapter"
31
+ ActiveRecord::DynamicTimeout::Mysql2AdapterExtension
32
+ when "ActiveRecord::ConnectionAdapters::TrilogyAdapter"
33
+ ActiveRecord::DynamicTimeout::TrilogyAdapterExtension
34
+ when "ActiveRecord::ConnectionAdapters::SQLite3Adapter"
35
+ ActiveRecord::DynamicTimeout::SqliteAdapterExtension
36
+ when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
37
+ ActiveRecord::DynamicTimeout::PostgresAdapterExtension
38
+ end
39
+ adapter_class.prepend(extension) if extension
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "initializer"
4
+
5
+ module ActiveRecord::DynamicTimeout
6
+ class Railtie < Rails::Railtie
7
+ initializer "active_record-dynamic_timeout.initialize", after: "active_record.initialize_database" do |app|
8
+ ActiveSupport.on_load :active_record do
9
+ ActiveRecord::DynamicTimeout::Initializer.initialize!
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveRecord
2
+ module DynamicTimeout
3
+ VERSION = '0.0.1.rc1'
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record"
4
+ require "active_support"
5
+
6
+ module ActiveRecord
7
+ module DynamicTimeout
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-dynamic_timeout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.rc1
5
+ platform: ruby
6
+ authors:
7
+ - Tristan Starck
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-09-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.1'
27
+ description: ActiveRecord extension for dynamically setting connection timeouts
28
+ email:
29
+ - tstarck@invoca.com
30
+ - Invoca Development
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - Appraisals
36
+ - Gemfile
37
+ - Gemfile.lock
38
+ - LICENSE.md
39
+ - README.md
40
+ - Rakefile
41
+ - activerecord-dynamic_timeout.gemspec
42
+ - lib/active_record/dynamic_timeout.rb
43
+ - lib/active_record/dynamic_timeout/extensions/abstract_adapter_extension.rb
44
+ - lib/active_record/dynamic_timeout/extensions/base_extension.rb
45
+ - lib/active_record/dynamic_timeout/extensions/mysql2_adapter_extension.rb
46
+ - lib/active_record/dynamic_timeout/extensions/postgres_adapter_extension.rb
47
+ - lib/active_record/dynamic_timeout/extensions/sqlite_adapter_extension.rb
48
+ - lib/active_record/dynamic_timeout/extensions/trilogy_adapter_extension.rb
49
+ - lib/active_record/dynamic_timeout/initializer.rb
50
+ - lib/active_record/dynamic_timeout/railtie.rb
51
+ - lib/active_record/dynamic_timeout/version.rb
52
+ homepage: https://github.com/Invoca/activerecord-dynamic_timeout
53
+ licenses:
54
+ - MIT
55
+ metadata:
56
+ allowed_push_host: https://rubygems.org
57
+ source_code_uri: https://github.com/Invoca/activerecord-dynamic_timeout
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">"
70
+ - !ruby/object:Gem::Version
71
+ version: 1.3.1
72
+ requirements: []
73
+ rubygems_version: 3.3.27
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: ActiveRecord extension for dynamically setting connection timeouts
77
+ test_files: []