add offline subkeys to dht record report

This commit is contained in:
Christien Rioux 2024-04-13 14:15:09 -04:00
parent e89359e1f5
commit 4a190a6853
7 changed files with 83 additions and 3 deletions

View File

@ -795,10 +795,19 @@ impl StorageManager {
"more subkeys returned locally than requested" "more subkeys returned locally than requested"
); );
// Get the offline subkeys for this record still only returning the ones we're inspecting
let offline_subkey_writes = inner
.offline_subkey_writes
.get(&key)
.map(|o| o.subkeys.clone())
.unwrap_or_default()
.intersect(&subkeys);
// If this is the maximum scope we're interested in, return the report // If this is the maximum scope we're interested in, return the report
if matches!(scope, DHTReportScope::Local) { if matches!(scope, DHTReportScope::Local) {
return Ok(DHTRecordReport::new( return Ok(DHTRecordReport::new(
local_inspect_result.subkeys, local_inspect_result.subkeys,
offline_subkey_writes,
local_inspect_result.seqs, local_inspect_result.seqs,
vec![], vec![],
)); ));
@ -864,6 +873,7 @@ impl StorageManager {
Ok(DHTRecordReport::new( Ok(DHTRecordReport::new(
result.inspect_result.subkeys, result.inspect_result.subkeys,
offline_subkey_writes,
local_inspect_result.seqs, local_inspect_result.seqs,
result.inspect_result.seqs, result.inspect_result.seqs,
)) ))

View File

@ -12,6 +12,8 @@ pub struct DHTRecordReport {
/// This may be a subset of the requested range if it exceeds the schema limits /// This may be a subset of the requested range if it exceeds the schema limits
/// or has more than 512 subkeys /// or has more than 512 subkeys
subkeys: ValueSubkeyRangeSet, subkeys: ValueSubkeyRangeSet,
/// The subkeys that have been writen offline that still need to be flushed
offline_subkeys: ValueSubkeyRangeSet,
/// The sequence numbers of each subkey requested from a locally stored DHT Record /// The sequence numbers of each subkey requested from a locally stored DHT Record
local_seqs: Vec<ValueSeqNum>, local_seqs: Vec<ValueSeqNum>,
/// The sequence numbers of each subkey requested from the DHT over the network /// The sequence numbers of each subkey requested from the DHT over the network
@ -22,11 +24,13 @@ from_impl_to_jsvalue!(DHTRecordReport);
impl DHTRecordReport { impl DHTRecordReport {
pub fn new( pub fn new(
subkeys: ValueSubkeyRangeSet, subkeys: ValueSubkeyRangeSet,
offline_subkeys: ValueSubkeyRangeSet,
local_seqs: Vec<ValueSeqNum>, local_seqs: Vec<ValueSeqNum>,
network_seqs: Vec<ValueSeqNum>, network_seqs: Vec<ValueSeqNum>,
) -> Self { ) -> Self {
Self { Self {
subkeys, subkeys,
offline_subkeys,
local_seqs, local_seqs,
network_seqs, network_seqs,
} }
@ -35,6 +39,9 @@ impl DHTRecordReport {
pub fn subkeys(&self) -> &ValueSubkeyRangeSet { pub fn subkeys(&self) -> &ValueSubkeyRangeSet {
&self.subkeys &self.subkeys
} }
pub fn offline_subkeys(&self) -> &ValueSubkeyRangeSet {
&self.offline_subkeys
}
pub fn local_seqs(&self) -> &[ValueSeqNum] { pub fn local_seqs(&self) -> &[ValueSeqNum] {
&self.local_seqs &self.local_seqs
} }
@ -47,8 +54,9 @@ impl fmt::Debug for DHTRecordReport {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"DHTRecordReport {{\n subkeys: {:?}\n local_seqs:\n{}\n remote_seqs:\n{}\n}}\n", "DHTRecordReport {{\n subkeys: {:?}\n offline_subkeys: {:?}\n local_seqs:\n{}\n remote_seqs:\n{}\n}}\n",
&self.subkeys, &self.subkeys,
&self.offline_subkeys,
&debug_seqs(&self.local_seqs), &debug_seqs(&self.local_seqs),
&debug_seqs(&self.network_seqs) &debug_seqs(&self.network_seqs)
) )

View File

@ -246,6 +246,7 @@ class RouteBlob with _$RouteBlob {
class DHTRecordReport with _$DHTRecordReport { class DHTRecordReport with _$DHTRecordReport {
const factory DHTRecordReport({ const factory DHTRecordReport({
required List<ValueSubkeyRange> subkeys, required List<ValueSubkeyRange> subkeys,
required List<ValueSubkeyRange> offlineSubkeys,
required List<int> localSeqs, required List<int> localSeqs,
required List<int> networkSeqs, required List<int> networkSeqs,
}) = _DHTRecordReport; }) = _DHTRecordReport;

View File

@ -1363,6 +1363,8 @@ DHTRecordReport _$DHTRecordReportFromJson(Map<String, dynamic> json) {
/// @nodoc /// @nodoc
mixin _$DHTRecordReport { mixin _$DHTRecordReport {
List<ValueSubkeyRange> get subkeys => throw _privateConstructorUsedError; List<ValueSubkeyRange> get subkeys => throw _privateConstructorUsedError;
List<ValueSubkeyRange> get offlineSubkeys =>
throw _privateConstructorUsedError;
List<int> get localSeqs => throw _privateConstructorUsedError; List<int> get localSeqs => throw _privateConstructorUsedError;
List<int> get networkSeqs => throw _privateConstructorUsedError; List<int> get networkSeqs => throw _privateConstructorUsedError;
@ -1380,6 +1382,7 @@ abstract class $DHTRecordReportCopyWith<$Res> {
@useResult @useResult
$Res call( $Res call(
{List<ValueSubkeyRange> subkeys, {List<ValueSubkeyRange> subkeys,
List<ValueSubkeyRange> offlineSubkeys,
List<int> localSeqs, List<int> localSeqs,
List<int> networkSeqs}); List<int> networkSeqs});
} }
@ -1398,6 +1401,7 @@ class _$DHTRecordReportCopyWithImpl<$Res, $Val extends DHTRecordReport>
@override @override
$Res call({ $Res call({
Object? subkeys = null, Object? subkeys = null,
Object? offlineSubkeys = null,
Object? localSeqs = null, Object? localSeqs = null,
Object? networkSeqs = null, Object? networkSeqs = null,
}) { }) {
@ -1406,6 +1410,10 @@ class _$DHTRecordReportCopyWithImpl<$Res, $Val extends DHTRecordReport>
? _value.subkeys ? _value.subkeys
: subkeys // ignore: cast_nullable_to_non_nullable : subkeys // ignore: cast_nullable_to_non_nullable
as List<ValueSubkeyRange>, as List<ValueSubkeyRange>,
offlineSubkeys: null == offlineSubkeys
? _value.offlineSubkeys
: offlineSubkeys // ignore: cast_nullable_to_non_nullable
as List<ValueSubkeyRange>,
localSeqs: null == localSeqs localSeqs: null == localSeqs
? _value.localSeqs ? _value.localSeqs
: localSeqs // ignore: cast_nullable_to_non_nullable : localSeqs // ignore: cast_nullable_to_non_nullable
@ -1428,6 +1436,7 @@ abstract class _$$DHTRecordReportImplCopyWith<$Res>
@useResult @useResult
$Res call( $Res call(
{List<ValueSubkeyRange> subkeys, {List<ValueSubkeyRange> subkeys,
List<ValueSubkeyRange> offlineSubkeys,
List<int> localSeqs, List<int> localSeqs,
List<int> networkSeqs}); List<int> networkSeqs});
} }
@ -1444,6 +1453,7 @@ class __$$DHTRecordReportImplCopyWithImpl<$Res>
@override @override
$Res call({ $Res call({
Object? subkeys = null, Object? subkeys = null,
Object? offlineSubkeys = null,
Object? localSeqs = null, Object? localSeqs = null,
Object? networkSeqs = null, Object? networkSeqs = null,
}) { }) {
@ -1452,6 +1462,10 @@ class __$$DHTRecordReportImplCopyWithImpl<$Res>
? _value._subkeys ? _value._subkeys
: subkeys // ignore: cast_nullable_to_non_nullable : subkeys // ignore: cast_nullable_to_non_nullable
as List<ValueSubkeyRange>, as List<ValueSubkeyRange>,
offlineSubkeys: null == offlineSubkeys
? _value._offlineSubkeys
: offlineSubkeys // ignore: cast_nullable_to_non_nullable
as List<ValueSubkeyRange>,
localSeqs: null == localSeqs localSeqs: null == localSeqs
? _value._localSeqs ? _value._localSeqs
: localSeqs // ignore: cast_nullable_to_non_nullable : localSeqs // ignore: cast_nullable_to_non_nullable
@ -1469,9 +1483,11 @@ class __$$DHTRecordReportImplCopyWithImpl<$Res>
class _$DHTRecordReportImpl implements _DHTRecordReport { class _$DHTRecordReportImpl implements _DHTRecordReport {
const _$DHTRecordReportImpl( const _$DHTRecordReportImpl(
{required final List<ValueSubkeyRange> subkeys, {required final List<ValueSubkeyRange> subkeys,
required final List<ValueSubkeyRange> offlineSubkeys,
required final List<int> localSeqs, required final List<int> localSeqs,
required final List<int> networkSeqs}) required final List<int> networkSeqs})
: _subkeys = subkeys, : _subkeys = subkeys,
_offlineSubkeys = offlineSubkeys,
_localSeqs = localSeqs, _localSeqs = localSeqs,
_networkSeqs = networkSeqs; _networkSeqs = networkSeqs;
@ -1486,6 +1502,14 @@ class _$DHTRecordReportImpl implements _DHTRecordReport {
return EqualUnmodifiableListView(_subkeys); return EqualUnmodifiableListView(_subkeys);
} }
final List<ValueSubkeyRange> _offlineSubkeys;
@override
List<ValueSubkeyRange> get offlineSubkeys {
if (_offlineSubkeys is EqualUnmodifiableListView) return _offlineSubkeys;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_offlineSubkeys);
}
final List<int> _localSeqs; final List<int> _localSeqs;
@override @override
List<int> get localSeqs { List<int> get localSeqs {
@ -1504,7 +1528,7 @@ class _$DHTRecordReportImpl implements _DHTRecordReport {
@override @override
String toString() { String toString() {
return 'DHTRecordReport(subkeys: $subkeys, localSeqs: $localSeqs, networkSeqs: $networkSeqs)'; return 'DHTRecordReport(subkeys: $subkeys, offlineSubkeys: $offlineSubkeys, localSeqs: $localSeqs, networkSeqs: $networkSeqs)';
} }
@override @override
@ -1513,6 +1537,8 @@ class _$DHTRecordReportImpl implements _DHTRecordReport {
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$DHTRecordReportImpl && other is _$DHTRecordReportImpl &&
const DeepCollectionEquality().equals(other._subkeys, _subkeys) && const DeepCollectionEquality().equals(other._subkeys, _subkeys) &&
const DeepCollectionEquality()
.equals(other._offlineSubkeys, _offlineSubkeys) &&
const DeepCollectionEquality() const DeepCollectionEquality()
.equals(other._localSeqs, _localSeqs) && .equals(other._localSeqs, _localSeqs) &&
const DeepCollectionEquality() const DeepCollectionEquality()
@ -1524,6 +1550,7 @@ class _$DHTRecordReportImpl implements _DHTRecordReport {
int get hashCode => Object.hash( int get hashCode => Object.hash(
runtimeType, runtimeType,
const DeepCollectionEquality().hash(_subkeys), const DeepCollectionEquality().hash(_subkeys),
const DeepCollectionEquality().hash(_offlineSubkeys),
const DeepCollectionEquality().hash(_localSeqs), const DeepCollectionEquality().hash(_localSeqs),
const DeepCollectionEquality().hash(_networkSeqs)); const DeepCollectionEquality().hash(_networkSeqs));
@ -1545,6 +1572,7 @@ class _$DHTRecordReportImpl implements _DHTRecordReport {
abstract class _DHTRecordReport implements DHTRecordReport { abstract class _DHTRecordReport implements DHTRecordReport {
const factory _DHTRecordReport( const factory _DHTRecordReport(
{required final List<ValueSubkeyRange> subkeys, {required final List<ValueSubkeyRange> subkeys,
required final List<ValueSubkeyRange> offlineSubkeys,
required final List<int> localSeqs, required final List<int> localSeqs,
required final List<int> networkSeqs}) = _$DHTRecordReportImpl; required final List<int> networkSeqs}) = _$DHTRecordReportImpl;
@ -1554,6 +1582,8 @@ abstract class _DHTRecordReport implements DHTRecordReport {
@override @override
List<ValueSubkeyRange> get subkeys; List<ValueSubkeyRange> get subkeys;
@override @override
List<ValueSubkeyRange> get offlineSubkeys;
@override
List<int> get localSeqs; List<int> get localSeqs;
@override @override
List<int> get networkSeqs; List<int> get networkSeqs;

View File

@ -116,6 +116,9 @@ _$DHTRecordReportImpl _$$DHTRecordReportImplFromJson(
subkeys: (json['subkeys'] as List<dynamic>) subkeys: (json['subkeys'] as List<dynamic>)
.map(ValueSubkeyRange.fromJson) .map(ValueSubkeyRange.fromJson)
.toList(), .toList(),
offlineSubkeys: (json['offline_subkeys'] as List<dynamic>)
.map(ValueSubkeyRange.fromJson)
.toList(),
localSeqs: localSeqs:
(json['local_seqs'] as List<dynamic>).map((e) => e as int).toList(), (json['local_seqs'] as List<dynamic>).map((e) => e as int).toList(),
networkSeqs: networkSeqs:
@ -126,6 +129,8 @@ Map<String, dynamic> _$$DHTRecordReportImplToJson(
_$DHTRecordReportImpl instance) => _$DHTRecordReportImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'subkeys': instance.subkeys.map((e) => e.toJson()).toList(), 'subkeys': instance.subkeys.map((e) => e.toJson()).toList(),
'offline_subkeys':
instance.offlineSubkeys.map((e) => e.toJson()).toList(),
'local_seqs': instance.localSeqs, 'local_seqs': instance.localSeqs,
'network_seqs': instance.networkSeqs, 'network_seqs': instance.networkSeqs,
}; };

View File

@ -2805,6 +2805,7 @@
"required": [ "required": [
"local_seqs", "local_seqs",
"network_seqs", "network_seqs",
"offline_subkeys",
"subkeys" "subkeys"
], ],
"properties": { "properties": {
@ -2826,6 +2827,27 @@
"minimum": 0.0 "minimum": 0.0
} }
}, },
"offline_subkeys": {
"description": "The subkeys that have been writen offline that still need to be flushed",
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "integer",
"format": "uint32",
"minimum": 0.0
},
{
"type": "integer",
"format": "uint32",
"minimum": 0.0
}
],
"maxItems": 2,
"minItems": 2
}
},
"subkeys": { "subkeys": {
"description": "The actual subkey range within the schema being reported on This may be a subset of the requested range if it exceeds the schema limits or has more than 512 subkeys", "description": "The actual subkey range within the schema being reported on This may be a subset of the requested range if it exceeds the schema limits or has more than 512 subkeys",
"type": "array", "type": "array",

View File

@ -382,26 +382,30 @@ class DHTRecordDescriptor:
class DHTRecordReport: class DHTRecordReport:
subkeys: list[tuple[ValueSubkey, ValueSubkey]] subkeys: list[tuple[ValueSubkey, ValueSubkey]]
offline_subkeys: list[tuple[ValueSubkey, ValueSubkey]]
local_seqs: list[ValueSeqNum] local_seqs: list[ValueSeqNum]
network_seqs: list[ValueSeqNum] network_seqs: list[ValueSeqNum]
def __init__( def __init__(
self, self,
subkeys: list[tuple[ValueSubkey, ValueSubkey]], subkeys: list[tuple[ValueSubkey, ValueSubkey]],
offline_subkeys: list[tuple[ValueSubkey, ValueSubkey]],
local_seqs: list[ValueSeqNum], local_seqs: list[ValueSeqNum],
network_seqs: list[ValueSeqNum], network_seqs: list[ValueSeqNum],
): ):
self.subkeys = subkeys self.subkeys = subkeys
self.offline_subkey = offline_subkeys
self.local_seqs = local_seqs self.local_seqs = local_seqs
self.network_seqs = network_seqs self.network_seqs = network_seqs
def __repr__(self) -> str: def __repr__(self) -> str:
return f"<{self.__class__.__name__}(subkeys={self.subkeys!r}, local_seqs={self.local_seqs!r}, network_seqs={self.network_seqs!r})>" return f"<{self.__class__.__name__}(subkeys={self.subkeys!r}, offline_subkeys={self.offline_subkeys!r}, local_seqs={self.local_seqs!r}, network_seqs={self.network_seqs!r})>"
@classmethod @classmethod
def from_json(cls, j: dict) -> Self: def from_json(cls, j: dict) -> Self:
return cls( return cls(
[[p[0], p[1]] for p in j["subkeys"]], [[p[0], p[1]] for p in j["subkeys"]],
[[p[0], p[1]] for p in j["offline_subkeys"]],
[ValueSeqNum(s) for s in j["local_seqs"]], [ValueSeqNum(s) for s in j["local_seqs"]],
[ValueSeqNum(s) for s in j["network_seqs"]], [ValueSeqNum(s) for s in j["network_seqs"]],
) )