double_entry 0.7.2 → 0.8.0

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 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