mysql_retry_lost_connection 0.0.1

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.
Files changed (3) hide show
  1. data/README +63 -0
  2. data/lib/mysql_retry_lost_connection.rb +23 -0
  3. metadata +47 -0
data/README ADDED
@@ -0,0 +1,63 @@
1
+ Has your Rails app ever thrown the 'Lost Connection to MySQL
2
+ server' exception? I love that error. How about 'MySQL server has gone
3
+ away?' That.s a good one too. If you're a fan of these exceptions then
4
+ stop reading now because I'm about to make them go away.
5
+
6
+ Rails is set up to handle database connections in such a way that the
7
+ likelihood of hitting these errors increases with the size of your
8
+ code base. ActiveRecord maintains one database connection per model. If
9
+ you use that database command often enough then it times out resulting
10
+ in the errors listed above. You can set the timeout interval in your
11
+ environment.rb with this:
12
+
13
+ ActiveRecord::Base.verification_timeout = 14400
14
+
15
+ If your app only has a handful of models and you hit actions that
16
+ trigger activity on each model.s connection frequently enough then
17
+ bumping up the interval in the above config might just be a good enough
18
+ solution for you. But when you keep adding models to your app to keep
19
+ up with feature requests then you.ll eventually have a user execute a
20
+ code path on a process whose database connection has timed out. We have
21
+ 123 models at Zvents and counting. We got to the point where Increasing
22
+ the verification_timeout wasn't really helping - we still hit a handful
23
+ of connections timeouts on models that didn't receive a lot of usage
24
+ (backend stuff mostly).
25
+
26
+ The solution, quite simply, is to have the database adapter reconnect
27
+ to the database when it detects a lost connection. It's not an original
28
+ or groundbreaking idea, but I couldn.t any plugins so I threw together
29
+ the mysql_retry_lost_connection plugin. It looks like this:
30
+
31
+ module ActiveRecord
32
+ module ConnectionAdapters
33
+ class MysqlAdapter
34
+ def execute(sql, name = nil) #:nodoc:
35
+ reconnect_lost_connections = true
36
+ begin
37
+ log(sql, name) { @connection.query(sql) }
38
+ rescue ActiveRecord::StatementInvalid => exception
39
+ RAILS_DEFAULT_LOGGER.info("ActiveRecord::StatementInvalid Error: #{exception.message}\n#{exception.backtrace.join("\n")}")
40
+ if reconnect_lost_connections and exception.message =~ /(Lost connection to MySQL server during query|MySQL server has gone away)/
41
+ reconnect_lost_connections = false
42
+ reconnect!
43
+ retry
44
+ elsif exception.message.split(":").first =~ /Packets out of order/
45
+ raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
46
+ else
47
+ raise
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ We've been running it in production for a couple weeks with no side
56
+ effects - and lost connections are just a happy memory now.
57
+
58
+ I'm not entirely happy with the code. Instead of clobbering the existing
59
+ execute method it should probably use alias_method to wrap the existing
60
+ method. That would make it more resilient to changes to the underlying
61
+ code in future Rails releases. But it works for me and I'm hitting
62
+ the sack. Free beer to the first person who rewrites it that manner or
63
+ improves it any other way.
@@ -0,0 +1,23 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class MysqlAdapter
4
+ def execute(sql, name = nil) #:nodoc:
5
+ reconnect_lost_connections = true
6
+ begin
7
+ log(sql, name) { @connection.query(sql) }
8
+ rescue ActiveRecord::StatementInvalid => exception
9
+ RAILS_DEFAULT_LOGGER.info("ActiveRecord::StatementInvalid Error: #{exception.message}\n#{exception.backtrace.join("\n")}")
10
+ if reconnect_lost_connections and exception.message =~ /(Lost connection to MySQL server during query|MySQL server has gone away)/
11
+ reconnect_lost_connections = false
12
+ reconnect!
13
+ retry
14
+ elsif exception.message.split(":").first =~ /Packets out of order/
15
+ raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
16
+ else
17
+ raise
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: mysql_retry_lost_connection
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-07-01 00:00:00 -07:00
8
+ summary: Reconnect to the MySQL server when you hit a lost connection error
9
+ require_paths:
10
+ - lib
11
+ email: tyler.kovacs@zvents.com
12
+ homepage: http://www.sparecycles.org/2007/7/2/saying-goodbye-to-lost-connections-in-rails
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: mysql_retry_lost_connection
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Tyler Kovacs
31
+ files:
32
+ - lib/mysql_retry_lost_connection.rb
33
+ - README
34
+ test_files: []
35
+
36
+ rdoc_options: []
37
+
38
+ extra_rdoc_files:
39
+ - README
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ requirements: []
45
+
46
+ dependencies: []
47
+