active-record-transactioner 0.0.4 → 0.0.5
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 +7 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +43 -6
- data/VERSION +1 -1
- data/active-record-transactioner.gemspec +10 -7
- data/lib/active-record-transactioner.rb +41 -3
- data/spec/active-record-transactioner_spec.rb +10 -0
- data/spec/test_classes/active-record-transactioner-test-class.rb +9 -1
- metadata +25 -24
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 6ff5f7c2e010ea51c857be4b595aff6a11fc6a29
|
|
4
|
+
data.tar.gz: c1b7216f9189778553b7455faf98d33760658683
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8a4511fa3b9124dd3173097b6601c23af067afc4ac1964a251e3e80045aa282b0bd8431159d4385211dd979c12b5b2691166e36a169f4e4208fb68cb66a2015d
|
|
7
|
+
data.tar.gz: a2e7df57feb26de445f1bb4a416d67265ce16aac5cbb23a2ca9528d768fc10251f67d8dd261e90dfad5cd7be21653ff9af2a225ada422209277f93db0b02fa22
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,15 +1,50 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: http://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
+
addressable (2.3.6)
|
|
5
|
+
builder (3.2.2)
|
|
6
|
+
descendants_tracker (0.0.4)
|
|
7
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
4
8
|
diff-lcs (1.1.3)
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
faraday (0.9.0)
|
|
10
|
+
multipart-post (>= 1.2, < 3)
|
|
11
|
+
git (1.2.6)
|
|
12
|
+
github_api (0.11.3)
|
|
13
|
+
addressable (~> 2.3)
|
|
14
|
+
descendants_tracker (~> 0.0.1)
|
|
15
|
+
faraday (~> 0.8, < 0.10)
|
|
16
|
+
hashie (>= 1.2)
|
|
17
|
+
multi_json (>= 1.7.5, < 2.0)
|
|
18
|
+
nokogiri (~> 1.6.0)
|
|
19
|
+
oauth2
|
|
20
|
+
hashie (2.1.1)
|
|
21
|
+
highline (1.6.21)
|
|
22
|
+
jeweler (2.0.1)
|
|
23
|
+
builder
|
|
24
|
+
bundler (>= 1.0)
|
|
8
25
|
git (>= 1.2.5)
|
|
26
|
+
github_api
|
|
27
|
+
highline (>= 1.6.15)
|
|
28
|
+
nokogiri (>= 1.5.10)
|
|
9
29
|
rake
|
|
10
30
|
rdoc
|
|
11
|
-
json (1.
|
|
12
|
-
|
|
31
|
+
json (1.8.1)
|
|
32
|
+
jwt (0.1.13)
|
|
33
|
+
multi_json (>= 1.5)
|
|
34
|
+
mini_portile (0.6.0)
|
|
35
|
+
multi_json (1.10.0)
|
|
36
|
+
multi_xml (0.5.5)
|
|
37
|
+
multipart-post (2.0.0)
|
|
38
|
+
nokogiri (1.6.2.1)
|
|
39
|
+
mini_portile (= 0.6.0)
|
|
40
|
+
oauth2 (0.9.3)
|
|
41
|
+
faraday (>= 0.8, < 0.10)
|
|
42
|
+
jwt (~> 0.1.8)
|
|
43
|
+
multi_json (~> 1.3)
|
|
44
|
+
multi_xml (~> 0.5)
|
|
45
|
+
rack (~> 1.2)
|
|
46
|
+
rack (1.5.2)
|
|
47
|
+
rake (10.3.2)
|
|
13
48
|
rdoc (3.12.2)
|
|
14
49
|
json (~> 1.4)
|
|
15
50
|
rspec (2.8.0)
|
|
@@ -20,12 +55,14 @@ GEM
|
|
|
20
55
|
rspec-expectations (2.8.0)
|
|
21
56
|
diff-lcs (~> 1.1.2)
|
|
22
57
|
rspec-mocks (2.8.0)
|
|
58
|
+
thread_safe (0.3.3)
|
|
23
59
|
|
|
24
60
|
PLATFORMS
|
|
25
61
|
ruby
|
|
26
62
|
|
|
27
63
|
DEPENDENCIES
|
|
64
|
+
builder
|
|
28
65
|
bundler (>= 1.0.0)
|
|
29
|
-
jeweler (
|
|
66
|
+
jeweler (>= 1.8.4)
|
|
30
67
|
rdoc (~> 3.12)
|
|
31
68
|
rspec (~> 2.8.0)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.0.
|
|
1
|
+
0.0.5
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "active-record-transactioner"
|
|
8
|
-
s.version = "0.0.
|
|
8
|
+
s.version = "0.0.5"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Kasper Johansen"]
|
|
12
|
-
s.date = "
|
|
12
|
+
s.date = "2014-05-18"
|
|
13
13
|
s.description = "Queue up calls to specific models and execute them in transactions, after a certain number of models have been added."
|
|
14
14
|
s.email = "kj@gfish.com"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -34,28 +34,31 @@ Gem::Specification.new do |s|
|
|
|
34
34
|
s.homepage = "http://github.com/kaspernj/active-record-transactioner"
|
|
35
35
|
s.licenses = ["MIT"]
|
|
36
36
|
s.require_paths = ["lib"]
|
|
37
|
-
s.rubygems_version = "
|
|
37
|
+
s.rubygems_version = "2.0.7"
|
|
38
38
|
s.summary = "Queue up calls to specific models and execute them in transactions, after a certain number of models have been added."
|
|
39
39
|
|
|
40
40
|
if s.respond_to? :specification_version then
|
|
41
|
-
s.specification_version =
|
|
41
|
+
s.specification_version = 4
|
|
42
42
|
|
|
43
43
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
44
44
|
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
45
45
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
|
46
46
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
|
47
|
-
s.add_development_dependency(%q<jeweler>, ["
|
|
47
|
+
s.add_development_dependency(%q<jeweler>, [">= 1.8.4"])
|
|
48
|
+
s.add_development_dependency(%q<builder>, [">= 0"])
|
|
48
49
|
else
|
|
49
50
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
50
51
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
|
51
52
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
|
52
|
-
s.add_dependency(%q<jeweler>, ["
|
|
53
|
+
s.add_dependency(%q<jeweler>, [">= 1.8.4"])
|
|
54
|
+
s.add_dependency(%q<builder>, [">= 0"])
|
|
53
55
|
end
|
|
54
56
|
else
|
|
55
57
|
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
|
56
58
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
|
57
59
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
|
58
|
-
s.add_dependency(%q<jeweler>, ["
|
|
60
|
+
s.add_dependency(%q<jeweler>, [">= 1.8.4"])
|
|
61
|
+
s.add_dependency(%q<builder>, [">= 0"])
|
|
59
62
|
end
|
|
60
63
|
end
|
|
61
64
|
|
|
@@ -5,7 +5,9 @@ class ActiveRecordTransactioner
|
|
|
5
5
|
:call_args => [],
|
|
6
6
|
:call_method => :save!,
|
|
7
7
|
:transaction_method => :transaction,
|
|
8
|
-
:transaction_size => 1000
|
|
8
|
+
:transaction_size => 1000,
|
|
9
|
+
:max_running_threads => 2,
|
|
10
|
+
:debug => false
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
ALLOWED_ARGS = DEFAULT_ARGS.keys
|
|
@@ -22,6 +24,7 @@ class ActiveRecordTransactioner
|
|
|
22
24
|
@lock = Monitor.new
|
|
23
25
|
@lock_threads = Monitor.new
|
|
24
26
|
@lock_models = {}
|
|
27
|
+
@debug = @args[:debug]
|
|
25
28
|
|
|
26
29
|
if block_given?
|
|
27
30
|
begin
|
|
@@ -42,13 +45,15 @@ class ActiveRecordTransactioner
|
|
|
42
45
|
@models[klass] = [] if !@models.key?(klass)
|
|
43
46
|
@models[klass] << model
|
|
44
47
|
@count += 1
|
|
45
|
-
flush if @count >= @args[:transaction_size]
|
|
46
48
|
end
|
|
49
|
+
|
|
50
|
+
flush if @count >= @args[:transaction_size]
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
#Flushes the specified method on all the queued models in a thread for each type of model.
|
|
50
54
|
def flush
|
|
51
55
|
threads = []
|
|
56
|
+
wait_for_threads
|
|
52
57
|
|
|
53
58
|
@lock.synchronize do
|
|
54
59
|
@models.each do |klass, val|
|
|
@@ -63,8 +68,10 @@ class ActiveRecordTransactioner
|
|
|
63
68
|
thread = Thread.new do
|
|
64
69
|
begin
|
|
65
70
|
@lock_models[klass].synchronize do
|
|
71
|
+
debug "Opening new transaction by using '#{@args[:transaction_method]}'."
|
|
66
72
|
klass.__send__(@args[:transaction_method]) do
|
|
67
73
|
models.each do |model|
|
|
74
|
+
# debug "Saving #{model.class.name}(#{model.id}) with method #{@args[:call_method]}"
|
|
68
75
|
model.__send__(@args[:call_method], *@args[:call_args])
|
|
69
76
|
end
|
|
70
77
|
end
|
|
@@ -74,15 +81,21 @@ class ActiveRecordTransactioner
|
|
|
74
81
|
puts e.backtrace
|
|
75
82
|
|
|
76
83
|
if e.is_a?(NoMethodError) and e.message.to_s.include?("`reverse' for nil:NilClass")
|
|
77
|
-
puts
|
|
78
84
|
puts "Warning: Known Rails reverse error when using transaction - retrying in 2 sec."
|
|
79
85
|
sleep 2
|
|
80
86
|
puts "Retrying"
|
|
81
87
|
puts
|
|
82
88
|
retry
|
|
83
89
|
end
|
|
90
|
+
|
|
91
|
+
raise e
|
|
84
92
|
ensure
|
|
93
|
+
debug "Removing thread #{Thread.current.__id__}"
|
|
85
94
|
@threads.delete(Thread.current)
|
|
95
|
+
|
|
96
|
+
@lock.synchronize do
|
|
97
|
+
ActiveRecord::Base.connection.close if ActiveRecord::Base.connection
|
|
98
|
+
end
|
|
86
99
|
end
|
|
87
100
|
end
|
|
88
101
|
end
|
|
@@ -107,4 +120,29 @@ class ActiveRecordTransactioner
|
|
|
107
120
|
end
|
|
108
121
|
end
|
|
109
122
|
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def debug(str)
|
|
127
|
+
puts "{ActiveRecordTransactioner}: #{str}" if @debug
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def wait_for_threads
|
|
131
|
+
break_loop = false
|
|
132
|
+
while !break_loop
|
|
133
|
+
debug "Trying to lock..." if @debug
|
|
134
|
+
@lock.synchronize do
|
|
135
|
+
debug "Running threads: #{@threads.length} / #{@args[:max_running_threads]}"
|
|
136
|
+
if @threads.length < @args[:max_running_threads]
|
|
137
|
+
break_loop = true
|
|
138
|
+
else
|
|
139
|
+
debug "Waiting for threads #{@threads.length} / #{@args[:max_running_threads]}" if @debug
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
sleep 0.2
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
debug "Done waiting." if @debug
|
|
147
|
+
end
|
|
110
148
|
end
|
|
@@ -27,4 +27,14 @@ describe "ActiveRecordTransactioner" do
|
|
|
27
27
|
|
|
28
28
|
called.should eql(true)
|
|
29
29
|
end
|
|
30
|
+
|
|
31
|
+
it "should not fail under the Rails reverse bug" do
|
|
32
|
+
ActiveRecordTransactionerTestClass::ARGS[:nilraise] = true
|
|
33
|
+
trans = ActiveRecordTransactioner.new(:transaction_size => 1)
|
|
34
|
+
model1 = ActiveRecordTransactionerTestClass.new
|
|
35
|
+
trans.queue(model1)
|
|
36
|
+
trans.join
|
|
37
|
+
|
|
38
|
+
ActiveRecordTransactionerTestClass::ARGS[:nilraise].should eql(false)
|
|
39
|
+
end
|
|
30
40
|
end
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
class ActiveRecordTransactionerTestClass
|
|
2
|
-
attr_reader :save_called
|
|
2
|
+
attr_reader :save_called, :args
|
|
3
|
+
|
|
4
|
+
ARGS = {:nilraise => false}
|
|
3
5
|
|
|
4
6
|
def initialize
|
|
5
7
|
@save_called = false
|
|
6
8
|
end
|
|
7
9
|
|
|
8
10
|
def self.transaction
|
|
11
|
+
if ActiveRecordTransactionerTestClass::ARGS[:nilraise]
|
|
12
|
+
nilobj = nil
|
|
13
|
+
ActiveRecordTransactionerTestClass::ARGS[:nilraise] = false
|
|
14
|
+
nilobj.reverse
|
|
15
|
+
end
|
|
16
|
+
|
|
9
17
|
Thread.current[:trans] = self.name
|
|
10
18
|
|
|
11
19
|
begin
|
metadata
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active-record-transactioner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.0.5
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Kasper Johansen
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2014-05-18 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: rspec
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
17
|
- - ~>
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
@@ -22,7 +20,6 @@ dependencies:
|
|
|
22
20
|
type: :development
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
24
|
- - ~>
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
@@ -30,7 +27,6 @@ dependencies:
|
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
|
31
28
|
name: rdoc
|
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
30
|
requirements:
|
|
35
31
|
- - ~>
|
|
36
32
|
- !ruby/object:Gem::Version
|
|
@@ -38,7 +34,6 @@ dependencies:
|
|
|
38
34
|
type: :development
|
|
39
35
|
prerelease: false
|
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
37
|
requirements:
|
|
43
38
|
- - ~>
|
|
44
39
|
- !ruby/object:Gem::Version
|
|
@@ -46,35 +41,45 @@ dependencies:
|
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
|
47
42
|
name: bundler
|
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
44
|
requirements:
|
|
51
|
-
- -
|
|
45
|
+
- - '>='
|
|
52
46
|
- !ruby/object:Gem::Version
|
|
53
47
|
version: 1.0.0
|
|
54
48
|
type: :development
|
|
55
49
|
prerelease: false
|
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
none: false
|
|
58
51
|
requirements:
|
|
59
|
-
- -
|
|
52
|
+
- - '>='
|
|
60
53
|
- !ruby/object:Gem::Version
|
|
61
54
|
version: 1.0.0
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
|
63
56
|
name: jeweler
|
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
-
none: false
|
|
66
58
|
requirements:
|
|
67
|
-
- -
|
|
59
|
+
- - '>='
|
|
68
60
|
- !ruby/object:Gem::Version
|
|
69
61
|
version: 1.8.4
|
|
70
62
|
type: :development
|
|
71
63
|
prerelease: false
|
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
-
none: false
|
|
74
65
|
requirements:
|
|
75
|
-
- -
|
|
66
|
+
- - '>='
|
|
76
67
|
- !ruby/object:Gem::Version
|
|
77
68
|
version: 1.8.4
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: builder
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - '>='
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
78
83
|
description: Queue up calls to specific models and execute them in transactions, after
|
|
79
84
|
a certain number of models have been added.
|
|
80
85
|
email: kj@gfish.com
|
|
@@ -100,30 +105,26 @@ files:
|
|
|
100
105
|
homepage: http://github.com/kaspernj/active-record-transactioner
|
|
101
106
|
licenses:
|
|
102
107
|
- MIT
|
|
108
|
+
metadata: {}
|
|
103
109
|
post_install_message:
|
|
104
110
|
rdoc_options: []
|
|
105
111
|
require_paths:
|
|
106
112
|
- lib
|
|
107
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
|
-
none: false
|
|
109
114
|
requirements:
|
|
110
|
-
- -
|
|
115
|
+
- - '>='
|
|
111
116
|
- !ruby/object:Gem::Version
|
|
112
117
|
version: '0'
|
|
113
|
-
segments:
|
|
114
|
-
- 0
|
|
115
|
-
hash: 1215318973199029384
|
|
116
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
|
-
none: false
|
|
118
119
|
requirements:
|
|
119
|
-
- -
|
|
120
|
+
- - '>='
|
|
120
121
|
- !ruby/object:Gem::Version
|
|
121
122
|
version: '0'
|
|
122
123
|
requirements: []
|
|
123
124
|
rubyforge_project:
|
|
124
|
-
rubygems_version:
|
|
125
|
+
rubygems_version: 2.0.7
|
|
125
126
|
signing_key:
|
|
126
|
-
specification_version:
|
|
127
|
+
specification_version: 4
|
|
127
128
|
summary: Queue up calls to specific models and execute them in transactions, after
|
|
128
129
|
a certain number of models have been added.
|
|
129
130
|
test_files: []
|