odba 1.2.2 → 1.2.3
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/History.md +22 -0
- data/lib/odba/cache.rb +14 -8
- data/lib/odba/version.rb +1 -1
- data/test/test_cache.rb +30 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5870eb15332e2b3e862dd27adf014e175e46588d673527794988a3a876f61b7
|
|
4
|
+
data.tar.gz: 8209e0f9122128f21e004f9db3a2fc7b58686f1c2b6f802ce3be628d095cd343
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7a633a8aeecdd7d243bce697800a3163b9090cae5352609aac8139704594bb02e71521f443829efeb618e1882c7f94b19b014c03b4e606c62ba66832566c173
|
|
7
|
+
data.tar.gz: abb1a74dff537de863797b397185e05ef1c6301da2d0e51ffcd48b3621b6a89f5933534b4fca02067d305abcb5645988b8eb805a07432d4e9e358fbf9d2cf7ea
|
data/History.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
## 1.2.3 / 01.09.2026
|
|
2
|
+
|
|
3
|
+
1.2.2 narrowed the rescue around the peer notification in `Cache#next_id` too
|
|
4
|
+
far. "A peer we cannot reach" is not only `DRb::DRbError`: a reference into a
|
|
5
|
+
peer that has restarted, or whose entry has expired from the DRb object space,
|
|
6
|
+
raises `RangeError("invalid reference")` from `DRbObjectSpace#to_obj` - a
|
|
7
|
+
StandardError, and not a DRbError. 1.1.9's classless rescue absorbed it; 1.2.2
|
|
8
|
+
let it out and it reached the caller.
|
|
9
|
+
|
|
10
|
+
In oddb.org that showed up on the first night under 1.2.2: three index
|
|
11
|
+
rebuilds died with `invalid reference (druby://127.0.0.1:10000)`. An index
|
|
12
|
+
that is not built is a deferred index, and ODBA fills a deferred index in
|
|
13
|
+
`Cache#setup` - so the *next* process to start died on it too, before doing
|
|
14
|
+
any work of its own.
|
|
15
|
+
|
|
16
|
+
* `next_id` re-raises `OdbaDuplicateIdError` (the one exception that must
|
|
17
|
+
reach the retry, which is what 1.2.2 was for) and swallows every other
|
|
18
|
+
StandardError from a peer, as 1.1.9 did.
|
|
19
|
+
* Two regression tests, one per direction: a stale reference must not stop
|
|
20
|
+
the allocation, and the catch-all must not swallow the conflict again.
|
|
21
|
+
The first fails against 1.2.2 with the production error.
|
|
22
|
+
|
|
1
23
|
## 1.2.2 / 31.08.2026
|
|
2
24
|
|
|
3
25
|
Two processes on one database handed out the same odba_id. Whichever wrote
|
data/lib/odba/cache.rb
CHANGED
|
@@ -441,14 +441,20 @@ module ODBA
|
|
|
441
441
|
end
|
|
442
442
|
@peers.each do |peer|
|
|
443
443
|
peer.reserve_next_id id
|
|
444
|
-
rescue
|
|
445
|
-
#
|
|
446
|
-
#
|
|
447
|
-
#
|
|
448
|
-
#
|
|
449
|
-
#
|
|
450
|
-
|
|
451
|
-
|
|
444
|
+
rescue OdbaDuplicateIdError
|
|
445
|
+
# The one exception that must get through, to the retry below. Until
|
|
446
|
+
# 1.2.2 a bare rescue swallowed it, so the retry could never run and
|
|
447
|
+
# both processes kept the same id; whichever wrote last overwrote the
|
|
448
|
+
# other's row in `object`, and every reference to it then resolved to
|
|
449
|
+
# a foreign object.
|
|
450
|
+
raise
|
|
451
|
+
rescue StandardError
|
|
452
|
+
# Anything else means we could not reach this peer, and that must not
|
|
453
|
+
# stop the allocation. Naming DRb::DRbError alone is not enough, which
|
|
454
|
+
# 1.2.2 got wrong: a stale reference into a peer raises RangeError
|
|
455
|
+
# ("invalid reference", drb.rb DRbObjectSpace#to_obj), which is not a
|
|
456
|
+
# DRbError. On 01.09.2026 that took down three index rebuilds in
|
|
457
|
+
# oddb.org - the peer had simply gone away.
|
|
452
458
|
end
|
|
453
459
|
id
|
|
454
460
|
rescue OdbaDuplicateIdError
|
data/lib/odba/version.rb
CHANGED
data/test/test_cache.rb
CHANGED
|
@@ -57,6 +57,36 @@ module ODBA
|
|
|
57
57
|
@cache.instance_variable_set(:@peers, [peer])
|
|
58
58
|
assert_equal(100, @cache.next_id)
|
|
59
59
|
end
|
|
60
|
+
|
|
61
|
+
# And "cannot reach" is not only DRbError. A reference into a peer that
|
|
62
|
+
# has restarted or expired raises RangeError("invalid reference") from
|
|
63
|
+
# DRbObjectSpace#to_obj - a StandardError, not a DRbError. 1.2.2 named
|
|
64
|
+
# DRbError alone and so let it out: on 01.09.2026 three index rebuilds in
|
|
65
|
+
# oddb.org died on it, which 1.1.9's classless rescue had absorbed.
|
|
66
|
+
def test_a_stale_reference_into_a_peer_does_not_stop_the_allocation
|
|
67
|
+
@storage.should_receive(:next_id).and_return(100)
|
|
68
|
+
peer = flexmock("peer")
|
|
69
|
+
peer.should_receive(:reserve_next_id)
|
|
70
|
+
.and_raise(RangeError, "invalid reference")
|
|
71
|
+
@cache.instance_variable_set(:@peers, [peer])
|
|
72
|
+
assert_equal(100, @cache.next_id)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# The catch-all must not grow so wide that it takes the conflict with it
|
|
76
|
+
# again - the whole point of 1.2.2. One test for each direction.
|
|
77
|
+
def test_a_conflict_is_not_swallowed_by_the_catch_all
|
|
78
|
+
@storage.should_receive(:next_id).and_return(100, 101)
|
|
79
|
+
calls = 0
|
|
80
|
+
peer = flexmock("peer")
|
|
81
|
+
peer.should_receive(:reserve_next_id).and_return {
|
|
82
|
+
calls += 1
|
|
83
|
+
raise ODBA::OdbaDuplicateIdError, "taken" if calls == 1
|
|
84
|
+
true
|
|
85
|
+
}
|
|
86
|
+
@cache.instance_variable_set(:@peers, [peer])
|
|
87
|
+
assert_equal(101, @cache.next_id)
|
|
88
|
+
assert_equal(2, calls)
|
|
89
|
+
end
|
|
60
90
|
end
|
|
61
91
|
|
|
62
92
|
class TestCache < Test::Unit::TestCase
|