fresh_connection 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8989dd7a0aed3ff918db29ccf6efad0df8bdef02
4
- data.tar.gz: df4cc23bdd361747bf850ed5b56551bd27eae6ac
3
+ metadata.gz: a6cf45789101eb5867723358916e51d9830479c7
4
+ data.tar.gz: 829c2c642c9357cbd4e40966601d4e9fa05ccedb
5
5
  SHA512:
6
- metadata.gz: 78177496e1e8407aac405f6b3c9997bfb0a5abedda4648ea5d83002cca0931df2ef3e76b92532a1ec0d9bc9701611f87cc24d8ca40fa7804db40776fba75d6d4
7
- data.tar.gz: 1547a303c0fb1eea943a9b8fbc5cfef4d6bc709462d4512a792e3a736d2317472ea1ab798f0c4a35d944f5ae5d3ab60e08f5e2a403a59b387acadc5bc35643fd
6
+ metadata.gz: 43f069ab92bc1383f3bd3c48503e3fd4df75cbda1622b6a2c81d11241787e78aeced42c7a492160090029a5212e1b61184989546bb3f5d8d4fa7a46dd35d5f0a
7
+ data.tar.gz: f06dacf9d04f362810a0febd8421cd78fbf94fc2ece3fddecd6cffb2845359394c51dca0a6fc4b1ddcd5b3d9654dc9c1e3f675edd16bcc58cd0ad0c2df5bcdbd
@@ -0,0 +1,42 @@
1
+ module FreshConnection
2
+ class AbstractConnectionManager
3
+ EXCEPTION_MESSAGE_WHEN_SLAVE_SERVER_DOWN = [
4
+ "MySQL server has gone away",
5
+ "closed MySQL connection",
6
+ "Can't connect to local MySQL server"
7
+ ].map{|msg| Regexp.escape(msg)}.join("|")
8
+
9
+ def initialize
10
+ @mutex = Mutex.new
11
+ end
12
+
13
+ def slave_connection
14
+ end
15
+
16
+ def put_aside!
17
+ end
18
+
19
+ def recovery(failure_connection, exception)
20
+ false
21
+ end
22
+
23
+ def recoverable?
24
+ false
25
+ end
26
+
27
+ private
28
+
29
+ def synchronize
30
+ @mutex.synchronize{ yield }
31
+ end
32
+
33
+ def current_thread_id
34
+ Thread.current.object_id
35
+ end
36
+
37
+ def slave_down_message?(message)
38
+ /#{EXCEPTION_MESSAGE_WHEN_SLAVE_SERVER_DOWN}/o =~ message
39
+ end
40
+ end
41
+ end
42
+
@@ -13,9 +13,20 @@ module ActiveRecord
13
13
  private
14
14
 
15
15
  def change_connection
16
- master_connection, @connection =
17
- @connection, FreshConnection::SlaveConnection.raw_connection
18
- yield
16
+ retry_count = 0
17
+ master_connection = @connection
18
+ begin
19
+ slave_connection = FreshConnection::SlaveConnection.slave_connection
20
+ @connection = slave_connection.raw_connection
21
+ yield
22
+ rescue ActiveRecord::StatementInvalid => exception
23
+ if FreshConnection::SlaveConnection.recovery(slave_connection, exception)
24
+ retry_count += 1
25
+ retry if retry_count < FreshConnection::SlaveConnection.retry_limit
26
+ end
27
+
28
+ raise
29
+ end
19
30
  ensure
20
31
  @connection = master_connection
21
32
  end
@@ -1,27 +1,40 @@
1
- module FreshConnection
2
- class ConnectionManager
3
- def initialize
4
- @mutex = Mutex.new
5
- end
1
+ require 'fresh_connection/abstract_connection_manager'
6
2
 
3
+ module FreshConnection
4
+ class ConnectionManager < AbstractConnectionManager
7
5
  def slave_connection
8
- @mutex.synchronize do
9
- @slave_connections ||= {}
10
- @slave_connections[current_thread_id] ||= new_connection
6
+ synchronize do
7
+ slave_connections[current_thread_id] ||= new_connection
11
8
  end
12
9
  end
13
10
 
14
11
  def put_aside!
15
- @mutex.synchronize do
16
- @slave_connections ||= {}
17
- if c = @slave_connections.delete(current_thread_id)
12
+ synchronize do
13
+ if c = slave_connections.delete(current_thread_id)
18
14
  c.disconnect! rescue nil
19
15
  end
20
16
  end
21
17
  end
22
18
 
19
+ def recovery(failure_connection, exception)
20
+ if recoverable? && slave_down_message?(exception.message)
21
+ put_aside!
22
+ true
23
+ else
24
+ false
25
+ end
26
+ end
27
+
28
+ def recoverable?
29
+ true
30
+ end
31
+
23
32
  private
24
33
 
34
+ def slave_connections
35
+ @slave_connections ||= {}
36
+ end
37
+
25
38
  def new_connection
26
39
  ActiveRecord::Base.send("#{spec["adapter"]}_connection", spec)
27
40
  end
@@ -34,9 +47,5 @@ module FreshConnection
34
47
  ret = ActiveRecord::Base.configurations[Rails.env]
35
48
  ret.merge(ret["slave"] || {})
36
49
  end
37
-
38
- def current_thread_id
39
- Thread.current.object_id
40
- end
41
50
  end
42
51
  end
@@ -2,21 +2,12 @@ module FreshConnection
2
2
  class SlaveConnection
3
3
  COUNT = :fresh_connection_access_count
4
4
  TARGET = :fresh_connection_access_target
5
+ RETRY_LIMIT = 10
5
6
 
6
7
  class << self
7
8
  attr_writer :ignore_models, :ignore_configure_connection
8
9
 
9
- def raw_connection
10
- slave_connection.raw_connection
11
- end
12
-
13
- def slave_connection
14
- connection_manager.slave_connection
15
- end
16
-
17
- def put_aside!
18
- connection_manager.put_aside!
19
- end
10
+ delegate :slave_connection, :put_aside!, :recoverable?, :recovery, :to => :connection_manager
20
11
 
21
12
  def manage_access(model_klass, go_slave, &block)
22
13
  if ignore_model?(model_klass)
@@ -57,6 +48,10 @@ module FreshConnection
57
48
  @connection_manager_class = manager
58
49
  end
59
50
 
51
+ def retry_limit
52
+ RETRY_LIMIT
53
+ end
54
+
60
55
  private
61
56
 
62
57
  def force_master_access
@@ -1,4 +1,4 @@
1
1
  module FreshConnection
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fresh_connection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tsukasa OISHI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-13 00:00:00.000000000 Z
11
+ date: 2013-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -65,6 +65,7 @@ files:
65
65
  - Rakefile
66
66
  - fresh_connection.gemspec
67
67
  - lib/fresh_connection.rb
68
+ - lib/fresh_connection/abstract_connection_manager.rb
68
69
  - lib/fresh_connection/active_record/abstract_adapter.rb
69
70
  - lib/fresh_connection/active_record/mysql2_adapter.rb
70
71
  - lib/fresh_connection/active_record/relation.rb