legion-data 1.6.25 → 1.6.27
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/CHANGELOG.md +13 -0
- data/lib/legion/data/archiver.rb +1 -5
- data/lib/legion/data/audit_record.rb +24 -20
- data/lib/legion/data/model.rb +1 -1
- data/lib/legion/data/settings.rb +3 -2
- data/lib/legion/data/version.rb +1 -1
- data/lib/legion/data.rb +2 -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: d2fca06857473b0c009e6ab0ca7044f09b394ce3652adad2b35e57835bceb5eb
|
|
4
|
+
data.tar.gz: ea80dac3fee5e54500534c5399c4f1c5b47b9a68ee6c0d0bf0d5ebe344053531
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '009fcbd9de6e5dd5d8e74d1ccf2d21c8692a930ae15369ae19fccb2a5f7829982ba6bf79757c66af25d4cce32c5caaf4b8350316e98261676e1bc532485302d4'
|
|
7
|
+
data.tar.gz: d36ede441cdf282214ff9abc7836f2ba07f2eb02bce839f884bf074a7cacea3336ddfdb0182ff87c4e1ba63e54f0bc26c3d9eb1769b607474cc3a32197c814fd
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.6.27] - 2026-04-17
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- `load_sequel_model` now reads `settings[:models][:continue_on_load_fail]` (was erroneously reading `continue_on_fail`, a key that never existed — LoadError was always re-raised regardless of the setting). (Fixes #22)
|
|
9
|
+
- `load_models` now skips model loading when `settings[:models][:autoload]` is `false`, honoring the documented knob. (Fixes #22)
|
|
10
|
+
- Audit record live-path specs (`append`, `verify`, `walk`, `query_by_type`, immutability guards) are now self-sufficient: the `before` block reconnects the DB if a prior spec tore it down, eliminating 19 pending examples when running the full suite. (Fixes #22)
|
|
11
|
+
- Default `preconnect` changed from `'concurrently'` to `false`. The concurrent preconnect mode spawned background threads that emitted noisy connection errors when a network adapter was unreachable before dev-fallback could catch the failure. `false` preserves identical behavior for SQLite (default) and avoids the noise for production deployments where operators can opt-in explicitly. (Fixes #22)
|
|
12
|
+
|
|
13
|
+
## [1.6.26] - 2026-04-17
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- `connection_validation_timeout` default reduced from 600s to -1 (validate every checkout) for non-SQLite adapters. The previous 10-minute window meant stale PG connections from a VPN drop, sleep/wake, or network interface change were not evicted until the next scheduled validation cycle, causing `Sequel::DatabaseDisconnectError` to repeat on every actor tick. With -1, Sequel pings the connection on every pool checkout and discards dead connections immediately. (Fixes #28)
|
|
17
|
+
|
|
5
18
|
## [1.6.24] - 2026-04-13
|
|
6
19
|
|
|
7
20
|
### Added
|
data/lib/legion/data/archiver.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Legion
|
|
|
25
25
|
conn = Legion::Data.connection
|
|
26
26
|
conn.transaction do
|
|
27
27
|
parent_hash = latest_chain_hash(conn, chain_id)
|
|
28
|
-
ts = Time.now
|
|
28
|
+
ts = truncate_to_us(Time.now)
|
|
29
29
|
ch = compute_chain_hash(parent_hash, content_hash, ts, content_type)
|
|
30
30
|
sig = sign ? sign_record(ch) : nil
|
|
31
31
|
meta_json = metadata.empty? ? nil : Legion::JSON.dump(metadata)
|
|
@@ -104,31 +104,35 @@ module Legion
|
|
|
104
104
|
ds.order(Sequel.desc(:created_at)).limit(limit).all.map { |r| deserialize(r) }
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
# SHA-256 of "parent_hash:content_hash:
|
|
107
|
+
# SHA-256 of "parent_hash:content_hash:unix_ts_us:content_type".
|
|
108
108
|
#
|
|
109
|
-
# The timestamp is normalised to
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
109
|
+
# The timestamp is normalised to microseconds-since-epoch. PostgreSQL
|
|
110
|
+
# TIMESTAMP columns have microsecond precision, so nanosecond values
|
|
111
|
+
# written by Ruby would be truncated on read, causing recomputed hashes
|
|
112
|
+
# to diverge. Microsecond normalisation keeps write-time and read-time
|
|
113
|
+
# hashes identical across all supported adapters.
|
|
113
114
|
def compute_chain_hash(parent_hash, content_hash, timestamp, content_type)
|
|
114
|
-
|
|
115
|
-
Digest::SHA256.hexdigest("#{parent_hash}:#{content_hash}:#{
|
|
115
|
+
ts_us = normalise_timestamp_us(timestamp)
|
|
116
|
+
Digest::SHA256.hexdigest("#{parent_hash}:#{content_hash}:#{ts_us}:#{content_type}")
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
private
|
|
119
120
|
|
|
120
|
-
# Normalise a timestamp to integer
|
|
121
|
-
# whether the database returned a Time, DateTime, or String.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
121
|
+
# Normalise a timestamp to integer microseconds-since-epoch regardless of
|
|
122
|
+
# whether the database returned a Time, DateTime, or String. Always uses
|
|
123
|
+
# the absolute epoch value so timezone differences don't affect the hash.
|
|
124
|
+
def normalise_timestamp_us(timestamp)
|
|
125
|
+
t = case timestamp
|
|
126
|
+
when ::Time then timestamp
|
|
127
|
+
when ::DateTime then timestamp.to_time
|
|
128
|
+
else ::Time.parse(timestamp.to_s)
|
|
129
|
+
end
|
|
130
|
+
(t.to_r * 1_000_000).to_i
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def truncate_to_us(time)
|
|
134
|
+
us = (time.to_r * 1_000_000).to_i
|
|
135
|
+
::Time.at(Rational(us, 1_000_000))
|
|
132
136
|
end
|
|
133
137
|
|
|
134
138
|
def latest_chain_hash(conn, chain_id)
|
data/lib/legion/data/model.rb
CHANGED
|
@@ -37,7 +37,7 @@ module Legion
|
|
|
37
37
|
model
|
|
38
38
|
rescue LoadError => e
|
|
39
39
|
handle_exception(e, level: :fatal, operation: :load_sequel_model, model: model)
|
|
40
|
-
raise e unless Legion::Settings[:data][:models][:
|
|
40
|
+
raise e unless Legion::Settings[:data][:models][:continue_on_load_fail]
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|
data/lib/legion/data/settings.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Legion
|
|
|
35
35
|
# Connection pool
|
|
36
36
|
max_connections: 25,
|
|
37
37
|
pool_timeout: 5,
|
|
38
|
-
preconnect:
|
|
38
|
+
preconnect: false,
|
|
39
39
|
single_threaded: false,
|
|
40
40
|
test: true,
|
|
41
41
|
name: nil,
|
|
@@ -48,8 +48,9 @@ module Legion
|
|
|
48
48
|
sql_log_level: 'debug',
|
|
49
49
|
|
|
50
50
|
# Connection health (network adapters only, ignored for sqlite)
|
|
51
|
+
# -1 means validate on every checkout, catching stale connections from VPN/sleep/network changes immediately
|
|
51
52
|
connection_validation: true,
|
|
52
|
-
connection_validation_timeout:
|
|
53
|
+
connection_validation_timeout: -1,
|
|
53
54
|
connection_expiration: true,
|
|
54
55
|
connection_expiration_timeout: 14_400,
|
|
55
56
|
|
data/lib/legion/data/version.rb
CHANGED
data/lib/legion/data.rb
CHANGED