double_entry 0.7.2 → 0.8.0

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: 32faa0991a3e20450e5c310ed76831804f8f8489
4
- data.tar.gz: b4d643d8739f316dc7d0b3404bfd13d6bbc5f678
3
+ metadata.gz: e815a7e5aabf260a4697a11f7685d362c017cdfb
4
+ data.tar.gz: 416041a85f823156b3211c58edcb751a07ea60d1
5
5
  SHA512:
6
- metadata.gz: 3f23c6af662e48e0dd8e520111628faf5f9d59e5d6b3e10d5a9cd3cb94ec9f6f5d9829d5bc86636ec4f5cac7dc6ca502a6ef011baba6e4c3b70aa7944b5a042d
7
- data.tar.gz: 34d17bcd0b139a5dad177a588c737a5ef2b3704db52b83812b6dae3e2ac600a4eef4a2b4a642d11474e2cf074eeaebdb3d64e489e1c34033f4c67283bcb0791d
6
+ metadata.gz: 0b36f7c934a87f36ec0250d360b043e4a98c033bd74289eaa9cade1e120f35fa438376629bb8d099de122481f28411ecc4a6890641646e56ba49afad52d99312
7
+ data.tar.gz: 4c8a843ba84218611d2545b161f58cddbb03617c94564027f02e85957e6754d299d5381f37527e5cc0f7b3e58e05a4821fb27c82883b750fe139db61e901cf0c
@@ -1,4 +1,6 @@
1
1
  # encoding: utf-8
2
+ require "active_support/notifications"
3
+
2
4
  module ActiveRecord
3
5
 
4
6
  # These methods are available as class methods on ActiveRecord::Base.
@@ -21,6 +23,8 @@ module ActiveRecord
21
23
  yield
22
24
  rescue ActiveRecord::StatementInvalid => exception
23
25
  if exception.message =~ /deadlock/i || exception.message =~ /database is locked/i
26
+ ActiveSupport::Notifications.publish("deadlock_restart.active_record", :exception => exception)
27
+
24
28
  raise ActiveRecord::RestartTransaction
25
29
  else
26
30
  raise
@@ -49,6 +53,8 @@ module ActiveRecord
49
53
  yield
50
54
  rescue ActiveRecord::StatementInvalid, ActiveRecord::RecordNotUnique => exception
51
55
  if exception.message =~ /duplicate/i || exception.message =~ /ConstraintException/
56
+ ActiveSupport::Notifications.publish("duplicate_ignore.active_record", :exception => exception)
57
+
52
58
  # Just ignore it...someone else has already created the record.
53
59
  else
54
60
  raise
@@ -66,6 +72,8 @@ module ActiveRecord
66
72
  if exception.message =~ /deadlock/i || exception.message =~ /database is locked/i
67
73
  # Somebody else is in the midst of creating the record. We'd better
68
74
  # retry, so we ensure they're done before we move on.
75
+ ActiveSupport::Notifications.publish("deadlock_retry.active_record", :exception => exception)
76
+
69
77
  retry
70
78
  else
71
79
  raise
@@ -80,4 +88,5 @@ module ActiveRecord
80
88
 
81
89
  end
82
90
 
91
+
83
92
  ActiveRecord::Base.extend(ActiveRecord::LockingExtensions)
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ require "active_support/log_subscriber"
3
+
4
+ module ActiveRecord
5
+ module LockingExtensions
6
+ class LogSubscriber < ActiveSupport::LogSubscriber
7
+ def deadlock_restart(event)
8
+ info "Deadlock causing restart"
9
+ debug event[:exception]
10
+ end
11
+
12
+ def deadlock_retry(event)
13
+ info "Deadlock causing retry"
14
+ debug event[:exception]
15
+ end
16
+
17
+ def duplicate_ignore(event)
18
+ info "Duplicate ignored"
19
+ debug event[:exception]
20
+ end
21
+
22
+ def logger
23
+ ActiveRecord::Base.logger
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ ActiveRecord::LockingExtensions::LogSubscriber.attach_to :active_record
data/lib/double_entry.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'active_record'
3
3
  require 'active_record/locking_extensions'
4
+ require 'active_record/locking_extensions/log_subscriber'
4
5
  require 'active_support/all'
5
6
  require 'money'
6
7
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module DoubleEntry
4
- VERSION = "0.7.2"
4
+ VERSION = "0.8.0"
5
5
  end
@@ -17,15 +17,34 @@ describe ActiveRecord::LockingExtensions do
17
17
  end
18
18
 
19
19
  context "#with_restart_on_deadlock" do
20
- context "raises a ActiveRecord::RestartTransaction error if a deadlock occurs" do
21
- it "in mysql" do
22
- expect { User.with_restart_on_deadlock { raise MYSQL_DEADLOCK } }.to raise_error(ActiveRecord::RestartTransaction)
20
+ shared_examples "abstract adapter" do
21
+ it "raises a ActiveRecord::RestartTransaction error if a deadlock occurs" do
22
+ expect { User.with_restart_on_deadlock { raise exception } }.to raise_error(ActiveRecord::RestartTransaction)
23
23
  end
24
24
 
25
- it "in postgres" do
26
- expect { User.with_restart_on_deadlock { raise PG_DEADLOCK } }.to raise_error(ActiveRecord::RestartTransaction)
25
+ it "publishes a notification" do
26
+ expect(ActiveSupport::Notifications).to receive(:publish).with("deadlock_restart.active_record", hash_including(:exception => exception))
27
+ expect { User.with_restart_on_deadlock { raise exception } }.to raise_error
27
28
  end
28
29
  end
30
+
31
+ context "mysql" do
32
+ let(:exception) { MYSQL_DEADLOCK }
33
+
34
+ it_behaves_like "abstract adapter"
35
+ end
36
+
37
+ context "postgres" do
38
+ let(:exception) { PG_DEADLOCK }
39
+
40
+ it_behaves_like "abstract adapter"
41
+ end
42
+
43
+ context "sqlite" do
44
+ let(:exception) { SQLITE3_LOCK }
45
+
46
+ it_behaves_like "abstract adapter"
47
+ end
29
48
  end
30
49
 
31
50
  context "#create_ignoring_duplicates" do
@@ -36,27 +55,49 @@ describe ActiveRecord::LockingExtensions do
36
55
  expect { User.create_ignoring_duplicates! :username => "keith" }.to_not raise_error
37
56
  end
38
57
 
39
- context "retries the creation if a deadlock error is raised from the database" do
40
- it "in mysql" do
41
- expect(User).to receive(:create!).ordered.and_raise(MYSQL_DEADLOCK)
42
- expect(User).to receive(:create!).ordered.and_return(true)
58
+ it "publishes a notification when a duplicate is encountered" do
59
+ User.make! :username => "keith"
43
60
 
44
- expect { User.create_ignoring_duplicates! }.to_not raise_error
45
- end
61
+ expect(ActiveSupport::Notifications).to receive(:publish).with("duplicate_ignore.active_record", hash_including(:exception => kind_of(ActiveRecord::RecordNotUnique)))
46
62
 
47
- it "in postgres" do
48
- expect(User).to receive(:create!).ordered.and_raise(PG_DEADLOCK)
63
+ expect { User.create_ignoring_duplicates! :username => "keith" }.to_not raise_error
64
+ end
65
+
66
+ shared_examples "abstract adapter" do
67
+ it "retries the creation if a deadlock error is raised from the database" do
68
+ expect(User).to receive(:create!).ordered.and_raise(exception)
49
69
  expect(User).to receive(:create!).ordered.and_return(true)
50
70
 
51
71
  expect { User.create_ignoring_duplicates! }.to_not raise_error
52
72
  end
53
73
 
54
- it "in sqlite3" do
55
- expect(User).to receive(:create!).ordered.and_raise(SQLITE3_LOCK)
74
+ it "publishes a notification on each retry" do
75
+ expect(User).to receive(:create!).ordered.and_raise(exception)
76
+ expect(User).to receive(:create!).ordered.and_raise(exception)
56
77
  expect(User).to receive(:create!).ordered.and_return(true)
57
78
 
79
+ expect(ActiveSupport::Notifications).to receive(:publish).with("deadlock_retry.active_record", hash_including(:exception => exception)).twice
80
+
58
81
  expect { User.create_ignoring_duplicates! }.to_not raise_error
59
82
  end
60
83
  end
84
+
85
+ context "mysql" do
86
+ let(:exception) { MYSQL_DEADLOCK }
87
+
88
+ it_behaves_like "abstract adapter"
89
+ end
90
+
91
+ context "postgres" do
92
+ let(:exception) { PG_DEADLOCK }
93
+
94
+ it_behaves_like "abstract adapter"
95
+ end
96
+
97
+ context "sqlite" do
98
+ let(:exception) { SQLITE3_LOCK }
99
+
100
+ it_behaves_like "abstract adapter"
101
+ end
61
102
  end
62
103
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: double_entry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Sellitti
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2014-11-18 00:00:00.000000000 Z
18
+ date: 2014-11-19 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: money
@@ -237,6 +237,7 @@ files:
237
237
  - Rakefile
238
238
  - double_entry.gemspec
239
239
  - lib/active_record/locking_extensions.rb
240
+ - lib/active_record/locking_extensions/log_subscriber.rb
240
241
  - lib/double_entry.rb
241
242
  - lib/double_entry/account.rb
242
243
  - lib/double_entry/account_balance.rb