perobs 4.4.0 → 4.5.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 +4 -4
- data/lib/perobs/BigArrayNode.rb +10 -8
- data/lib/perobs/Cache.rb +13 -0
- data/lib/perobs/Log.rb +5 -0
- data/lib/perobs/Store.rb +16 -2
- data/lib/perobs/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90c77003da7bd628fa753bfe35918d8c702b433ac5113ba9fc206f7afa114f6c
|
4
|
+
data.tar.gz: c38f786cb10a040048b7d08b75c16baf034c116a3f9648ece3af7b50e7898446
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fea934c359190c3b171c99e4dbffb3af58ec2f9dd755eedc0acb7db556f0e2471bd3c527a2910e5d8f17cd59b3f1ca4079436bc80bd11ea5d6efa60f55a54e9
|
7
|
+
data.tar.gz: db71320a9672848a3e35088e7a8b3389278c987a1bea905336e3f8bfff6daeb27564724b6f9d681d364684a57ce8593021041626615dace155e1849b0944003b
|
data/lib/perobs/BigArrayNode.rb
CHANGED
@@ -135,27 +135,29 @@ module PEROBS
|
|
135
135
|
node = self
|
136
136
|
|
137
137
|
# Traverse the tree to find the right node to add or replace the value.
|
138
|
+
idx = index
|
138
139
|
while node do
|
139
140
|
# Once we have reached a leaf node we can insert or replace the value.
|
140
141
|
if node.is_leaf?
|
141
|
-
if
|
142
|
+
if idx >= node.values.size
|
142
143
|
node.fatal "Set index (#{index}) larger than values array " +
|
143
|
-
"(#{node.values.size})."
|
144
|
+
"(#{idx} >= #{node.values.size})."
|
144
145
|
end
|
145
|
-
node.values[
|
146
|
+
node.values[idx] = value
|
146
147
|
return
|
147
148
|
else
|
148
149
|
# Descend into the right child node to add the value to.
|
149
|
-
cidx = node.search_child_index(
|
150
|
-
if (
|
151
|
-
node.fatal "
|
150
|
+
cidx = node.search_child_index(idx)
|
151
|
+
if (idx -= node.offsets[cidx]) < 0
|
152
|
+
node.fatal "Idx (#{idx}) became negative while looking for " +
|
153
|
+
"index #{index}."
|
152
154
|
end
|
153
155
|
node = node.children[cidx]
|
154
156
|
end
|
155
157
|
end
|
156
158
|
|
157
159
|
node.fatal "Could not find proper node to set the value while " +
|
158
|
-
"looking for index #{index}"
|
160
|
+
"looking for index #{index}."
|
159
161
|
end
|
160
162
|
|
161
163
|
# Insert the given value at the given index. All following values will be
|
@@ -811,7 +813,7 @@ module PEROBS
|
|
811
813
|
|
812
814
|
# Print and log an error message for the node.
|
813
815
|
def fatal(msg)
|
814
|
-
msg = "Fatal error in BigArray node @#{@_id}: #{msg}\n"
|
816
|
+
msg = "Fatal error in BigArray node @#{@_id}: #{msg}\n"
|
815
817
|
$stderr.puts msg
|
816
818
|
PEROBS.log.fatal msg
|
817
819
|
end
|
data/lib/perobs/Cache.rb
CHANGED
@@ -165,10 +165,20 @@ module PEROBS
|
|
165
165
|
# active, the write cache is flushed before the transaction is started.
|
166
166
|
def begin_transaction
|
167
167
|
if @transaction_stack.empty?
|
168
|
+
if @transaction_thread
|
169
|
+
PEROBS.log.fatal 'transaction_thread must be nil'
|
170
|
+
end
|
171
|
+
@transaction_thread = Thread.current
|
168
172
|
# The new transaction is the top-level transaction. Flush the write
|
169
173
|
# buffer to save the current state of all objects.
|
170
174
|
flush
|
171
175
|
else
|
176
|
+
# Nested transactions are currently only supported within the same
|
177
|
+
# thread. If we are in another thread, raise TransactionInOtherThread
|
178
|
+
# to pause the calling thread for a bit.
|
179
|
+
if @transaction_thread != Thread.current
|
180
|
+
raise TransactionInOtherThread
|
181
|
+
end
|
172
182
|
# Save a copy of all objects that were modified during the enclosing
|
173
183
|
# transaction.
|
174
184
|
@transaction_stack.last.each do |id|
|
@@ -192,6 +202,7 @@ module PEROBS
|
|
192
202
|
# into the backend storage.
|
193
203
|
@transaction_stack.pop.each { |id| @transaction_objects[id]._sync }
|
194
204
|
@transaction_objects = ::Hash.new
|
205
|
+
@transaction_thread = nil
|
195
206
|
else
|
196
207
|
# A nested transaction completed successfully. We add the list of
|
197
208
|
# modified objects to the list of the enclosing transaction.
|
@@ -213,6 +224,7 @@ module PEROBS
|
|
213
224
|
@transaction_stack.pop.each do |id|
|
214
225
|
@transaction_objects[id]._restore(@transaction_stack.length)
|
215
226
|
end
|
227
|
+
@transaction_thread = nil
|
216
228
|
end
|
217
229
|
|
218
230
|
# Clear all cached entries. You must call flush before calling this
|
@@ -224,6 +236,7 @@ module PEROBS
|
|
224
236
|
@reads = ::Array.new(2 ** @bits)
|
225
237
|
@writes = ::Array.new(2 ** @bits)
|
226
238
|
@transaction_stack = ::Array.new
|
239
|
+
@transaction_thread = nil
|
227
240
|
@transaction_objects = ::Hash.new
|
228
241
|
end
|
229
242
|
|
data/lib/perobs/Log.rb
CHANGED
@@ -42,6 +42,11 @@ module PEROBS
|
|
42
42
|
# are caused by user error rather than program logic errors.
|
43
43
|
class UsageError < StandardError ; end
|
44
44
|
|
45
|
+
# This is the Exception type that will be thrown when a transaction start
|
46
|
+
# failed because there is an ongoing transaction from another thread in
|
47
|
+
# progress.
|
48
|
+
class TransactionInOtherThread < StandardError ; end
|
49
|
+
|
45
50
|
# The ILogger class is a singleton that provides a common logging mechanism
|
46
51
|
# to all objects. It exposes essentially the same interface as the Logger
|
47
52
|
# class, just as a singleton and extends fatal to raise an FatalError
|
data/lib/perobs/Store.rb
CHANGED
@@ -455,7 +455,21 @@ module PEROBS
|
|
455
455
|
# beginning of the transaction. The exception is passed on to the
|
456
456
|
# enclosing scope, so you probably want to handle it accordingly.
|
457
457
|
def transaction
|
458
|
-
|
458
|
+
transaction_not_started = true
|
459
|
+
while transaction_not_started do
|
460
|
+
begin
|
461
|
+
@lock.synchronize do
|
462
|
+
@cache.begin_transaction
|
463
|
+
# If we get to this point, the transaction was successfully
|
464
|
+
# started. We can exit the loop.
|
465
|
+
transaction_not_started = false
|
466
|
+
end
|
467
|
+
rescue TransactionInOtherThread
|
468
|
+
# sleep up to 50ms
|
469
|
+
sleep(rand(50) / 1000.0)
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
459
473
|
begin
|
460
474
|
yield if block_given?
|
461
475
|
rescue => e
|
@@ -547,7 +561,7 @@ module PEROBS
|
|
547
561
|
# Therefor no locking is needed or even possible. The GC can kick in at
|
548
562
|
# any time and we could be anywhere in the code. So there is a small
|
549
563
|
# risk for a race here, but it should not have any serious consequences.
|
550
|
-
if @in_memory_objects[id] == ruby_object_id
|
564
|
+
if @in_memory_objects && @in_memory_objects[id] == ruby_object_id
|
551
565
|
@in_memory_objects.delete(id)
|
552
566
|
@stats[:collected_objects] += 1
|
553
567
|
end
|
data/lib/perobs/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Schlaeger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02
|
11
|
+
date: 2022-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|