fanout debugging
This commit is contained in:
parent
fcd9772e00
commit
2c779b2257
@ -288,7 +288,11 @@ where
|
|||||||
}
|
}
|
||||||
// Wait for them to complete
|
// Wait for them to complete
|
||||||
timeout(timeout_ms, async {
|
timeout(timeout_ms, async {
|
||||||
while let Some(_) = unord.next().await {}
|
while let Some(_) = unord.next().await {
|
||||||
|
if self.clone().evaluate_done() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.into_timeout_or()
|
.into_timeout_or()
|
||||||
|
@ -13,7 +13,6 @@ struct OutboundGetValueContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StorageManager {
|
impl StorageManager {
|
||||||
|
|
||||||
/// Perform a 'get value' query on the network
|
/// Perform a 'get value' query on the network
|
||||||
pub async fn outbound_get_value(
|
pub async fn outbound_get_value(
|
||||||
&self,
|
&self,
|
||||||
@ -74,15 +73,14 @@ impl StorageManager {
|
|||||||
if let Some(descriptor) = gva.answer.descriptor {
|
if let Some(descriptor) = gva.answer.descriptor {
|
||||||
let mut ctx = context.lock();
|
let mut ctx = context.lock();
|
||||||
if ctx.descriptor.is_none() && ctx.schema.is_none() {
|
if ctx.descriptor.is_none() && ctx.schema.is_none() {
|
||||||
ctx.schema =
|
ctx.schema = Some(descriptor.schema().map_err(RPCError::invalid_format)?);
|
||||||
Some(descriptor.schema().map_err(RPCError::invalid_format)?);
|
|
||||||
ctx.descriptor = Some(descriptor);
|
ctx.descriptor = Some(descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the value if we got one and it is newer and it passes schema validation
|
// Keep the value if we got one and it is newer and it passes schema validation
|
||||||
if let Some(value) = gva.answer.value {
|
if let Some(value) = gva.answer.value {
|
||||||
log_stor!(debug "Got value back: len={}", value.value_data().data().len());
|
log_stor!(debug "Got value back: len={} seq={}", value.value_data().data().len(), value.value_data().seq());
|
||||||
let mut ctx = context.lock();
|
let mut ctx = context.lock();
|
||||||
|
|
||||||
// Ensure we have a schema and descriptor
|
// Ensure we have a schema and descriptor
|
||||||
@ -126,8 +124,7 @@ impl StorageManager {
|
|||||||
} else {
|
} else {
|
||||||
// If the sequence number is older, ignore it
|
// If the sequence number is older, ignore it
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// If we have no prior value, keep it
|
// If we have no prior value, keep it
|
||||||
ctx.value = Some(value);
|
ctx.value = Some(value);
|
||||||
// One node has shown us this value so far
|
// One node has shown us this value so far
|
||||||
@ -136,7 +133,7 @@ impl StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return peers if we have some
|
// Return peers if we have some
|
||||||
#[cfg(feature="network-result-extra")]
|
#[cfg(feature = "network-result-extra")]
|
||||||
log_stor!(debug "GetValue fanout call returned peers {}", gva.answer.peers.len());
|
log_stor!(debug "GetValue fanout call returned peers {}", gva.answer.peers.len());
|
||||||
|
|
||||||
Ok(Some(gva.answer.peers))
|
Ok(Some(gva.answer.peers))
|
||||||
@ -147,7 +144,8 @@ impl StorageManager {
|
|||||||
let check_done = |_closest_nodes: &[NodeRef]| {
|
let check_done = |_closest_nodes: &[NodeRef]| {
|
||||||
// If we have reached sufficient consensus, return done
|
// If we have reached sufficient consensus, return done
|
||||||
let ctx = context.lock();
|
let ctx = context.lock();
|
||||||
if ctx.value.is_some() && ctx.descriptor.is_some() && ctx.value_count >= consensus_count {
|
if ctx.value.is_some() && ctx.descriptor.is_some() && ctx.value_count >= consensus_count
|
||||||
|
{
|
||||||
return Some(());
|
return Some(());
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -167,14 +165,31 @@ impl StorageManager {
|
|||||||
|
|
||||||
match fanout_call.run().await {
|
match fanout_call.run().await {
|
||||||
// If we don't finish in the timeout (too much time passed checking for consensus)
|
// If we don't finish in the timeout (too much time passed checking for consensus)
|
||||||
TimeoutOr::Timeout |
|
TimeoutOr::Timeout => {
|
||||||
|
log_stor!(debug "GetValue Fanout Timeout");
|
||||||
|
// Return the best answer we've got
|
||||||
|
let ctx = context.lock();
|
||||||
|
Ok(SubkeyResult {
|
||||||
|
value: ctx.value.clone(),
|
||||||
|
descriptor: ctx.descriptor.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
// If we finished with consensus (enough nodes returning the same value)
|
// If we finished with consensus (enough nodes returning the same value)
|
||||||
TimeoutOr::Value(Ok(Some(()))) |
|
TimeoutOr::Value(Ok(Some(()))) => {
|
||||||
|
log_stor!(debug "GetValue Fanout Consensus");
|
||||||
|
// Return the best answer we've got
|
||||||
|
let ctx = context.lock();
|
||||||
|
Ok(SubkeyResult {
|
||||||
|
value: ctx.value.clone(),
|
||||||
|
descriptor: ctx.descriptor.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
// If we finished without consensus (ran out of nodes before getting consensus)
|
// If we finished without consensus (ran out of nodes before getting consensus)
|
||||||
TimeoutOr::Value(Ok(None)) => {
|
TimeoutOr::Value(Ok(None)) => {
|
||||||
// Return the best answer we've got
|
// Return the best answer we've got
|
||||||
let ctx = context.lock();
|
let ctx = context.lock();
|
||||||
Ok(SubkeyResult{
|
log_stor!(debug "GetValue Fanout No Consensus: {}", ctx.value_count);
|
||||||
|
Ok(SubkeyResult {
|
||||||
value: ctx.value.clone(),
|
value: ctx.value.clone(),
|
||||||
descriptor: ctx.descriptor.clone(),
|
descriptor: ctx.descriptor.clone(),
|
||||||
})
|
})
|
||||||
@ -182,22 +197,31 @@ impl StorageManager {
|
|||||||
// Failed
|
// Failed
|
||||||
TimeoutOr::Value(Err(e)) => {
|
TimeoutOr::Value(Err(e)) => {
|
||||||
// If we finished with an error, return that
|
// If we finished with an error, return that
|
||||||
|
log_stor!(debug "GetValue Fanout Error: {}", e);
|
||||||
Err(e.into())
|
Err(e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a recieved 'Get Value' query
|
/// Handle a recieved 'Get Value' query
|
||||||
pub async fn inbound_get_value(&self, key: TypedKey, subkey: ValueSubkey, want_descriptor: bool) -> VeilidAPIResult<NetworkResult<SubkeyResult>> {
|
pub async fn inbound_get_value(
|
||||||
|
&self,
|
||||||
|
key: TypedKey,
|
||||||
|
subkey: ValueSubkey,
|
||||||
|
want_descriptor: bool,
|
||||||
|
) -> VeilidAPIResult<NetworkResult<SubkeyResult>> {
|
||||||
let mut inner = self.lock().await?;
|
let mut inner = self.lock().await?;
|
||||||
let res = match inner.handle_get_remote_value(key, subkey, want_descriptor).await {
|
let res = match inner
|
||||||
|
.handle_get_remote_value(key, subkey, want_descriptor)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(VeilidAPIError::Internal { message }) => {
|
Err(VeilidAPIError::Internal { message }) => {
|
||||||
apibail_internal!(message);
|
apibail_internal!(message);
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Ok(NetworkResult::invalid_message(e));
|
return Ok(NetworkResult::invalid_message(e));
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
Ok(NetworkResult::value(res))
|
Ok(NetworkResult::value(res))
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ struct OutboundSetValueContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StorageManager {
|
impl StorageManager {
|
||||||
|
|
||||||
/// Perform a 'set value' query on the network
|
/// Perform a 'set value' query on the network
|
||||||
pub async fn outbound_set_value(
|
pub async fn outbound_set_value(
|
||||||
&self,
|
&self,
|
||||||
@ -49,7 +48,6 @@ impl StorageManager {
|
|||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
let descriptor = descriptor.clone();
|
let descriptor = descriptor.clone();
|
||||||
async move {
|
async move {
|
||||||
|
|
||||||
let send_descriptor = true; // xxx check if next_node needs the descriptor or not
|
let send_descriptor = true; // xxx check if next_node needs the descriptor or not
|
||||||
|
|
||||||
// get most recent value to send
|
// get most recent value to send
|
||||||
@ -81,6 +79,7 @@ impl StorageManager {
|
|||||||
|
|
||||||
// Keep the value if we got one and it is newer and it passes schema validation
|
// Keep the value if we got one and it is newer and it passes schema validation
|
||||||
if let Some(value) = sva.answer.value {
|
if let Some(value) = sva.answer.value {
|
||||||
|
log_stor!(debug "Got value back: len={} seq={}", value.value_data().data().len(), value.value_data().seq());
|
||||||
|
|
||||||
// Validate with schema
|
// Validate with schema
|
||||||
if !ctx.schema.check_subkey_value_data(
|
if !ctx.schema.check_subkey_value_data(
|
||||||
@ -106,9 +105,7 @@ impl StorageManager {
|
|||||||
// Skip this node and it's closer list because it is misbehaving
|
// Skip this node and it's closer list because it is misbehaving
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// It was set on this node and no newer value was found and returned,
|
// It was set on this node and no newer value was found and returned,
|
||||||
// so increase our consensus count
|
// so increase our consensus count
|
||||||
ctx.value_count += 1;
|
ctx.value_count += 1;
|
||||||
@ -116,7 +113,7 @@ impl StorageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return peers if we have some
|
// Return peers if we have some
|
||||||
#[cfg(feature="network-result-extra")]
|
#[cfg(feature = "network-result-extra")]
|
||||||
log_stor!(debug "SetValue fanout call returned peers {}", sva.answer.peers.len());
|
log_stor!(debug "SetValue fanout call returned peers {}", sva.answer.peers.len());
|
||||||
|
|
||||||
Ok(Some(sva.answer.peers))
|
Ok(Some(sva.answer.peers))
|
||||||
@ -147,18 +144,30 @@ impl StorageManager {
|
|||||||
|
|
||||||
match fanout_call.run().await {
|
match fanout_call.run().await {
|
||||||
// If we don't finish in the timeout (too much time passed checking for consensus)
|
// If we don't finish in the timeout (too much time passed checking for consensus)
|
||||||
TimeoutOr::Timeout |
|
TimeoutOr::Timeout => {
|
||||||
|
log_stor!(debug "SetValue Fanout Timeout");
|
||||||
|
// Return the best answer we've got
|
||||||
|
let ctx = context.lock();
|
||||||
|
Ok(ctx.value.clone())
|
||||||
|
}
|
||||||
// If we finished with consensus (enough nodes returning the same value)
|
// If we finished with consensus (enough nodes returning the same value)
|
||||||
TimeoutOr::Value(Ok(Some(()))) |
|
TimeoutOr::Value(Ok(Some(()))) => {
|
||||||
|
log_stor!(debug "SetValue Fanout Consensus");
|
||||||
|
// Return the best answer we've got
|
||||||
|
let ctx = context.lock();
|
||||||
|
Ok(ctx.value.clone())
|
||||||
|
}
|
||||||
// If we finished without consensus (ran out of nodes before getting consensus)
|
// If we finished without consensus (ran out of nodes before getting consensus)
|
||||||
TimeoutOr::Value(Ok(None)) => {
|
TimeoutOr::Value(Ok(None)) => {
|
||||||
// Return the best answer we've got
|
// Return the best answer we've got
|
||||||
let ctx = context.lock();
|
let ctx = context.lock();
|
||||||
|
log_stor!(debug "SetValue Fanout No Consensus: {}", ctx.value_count);
|
||||||
Ok(ctx.value.clone())
|
Ok(ctx.value.clone())
|
||||||
}
|
}
|
||||||
// Failed
|
// Failed
|
||||||
TimeoutOr::Value(Err(e)) => {
|
TimeoutOr::Value(Err(e)) => {
|
||||||
// If we finished with an error, return that
|
// If we finished with an error, return that
|
||||||
|
log_stor!(debug "SetValue Fanout Error: {}", e);
|
||||||
Err(e.into())
|
Err(e.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,7 +176,13 @@ impl StorageManager {
|
|||||||
/// Handle a recieved 'Set Value' query
|
/// Handle a recieved 'Set Value' query
|
||||||
/// Returns a None if the value passed in was set
|
/// Returns a None if the value passed in was set
|
||||||
/// Returns a Some(current value) if the value was older and the current value was kept
|
/// Returns a Some(current value) if the value was older and the current value was kept
|
||||||
pub async fn inbound_set_value(&self, key: TypedKey, subkey: ValueSubkey, value: SignedValueData, descriptor: Option<SignedValueDescriptor>) -> VeilidAPIResult<NetworkResult<Option<SignedValueData>>> {
|
pub async fn inbound_set_value(
|
||||||
|
&self,
|
||||||
|
key: TypedKey,
|
||||||
|
subkey: ValueSubkey,
|
||||||
|
value: SignedValueData,
|
||||||
|
descriptor: Option<SignedValueDescriptor>,
|
||||||
|
) -> VeilidAPIResult<NetworkResult<Option<SignedValueData>>> {
|
||||||
let mut inner = self.lock().await?;
|
let mut inner = self.lock().await?;
|
||||||
|
|
||||||
// See if this is a remote or local value
|
// See if this is a remote or local value
|
||||||
@ -198,7 +213,9 @@ impl StorageManager {
|
|||||||
if let Some(descriptor) = descriptor {
|
if let Some(descriptor) = descriptor {
|
||||||
// Descriptor must match last one if it is provided
|
// Descriptor must match last one if it is provided
|
||||||
if descriptor.cmp_no_sig(&last_descriptor) != cmp::Ordering::Equal {
|
if descriptor.cmp_no_sig(&last_descriptor) != cmp::Ordering::Equal {
|
||||||
return Ok(NetworkResult::invalid_message("setvalue descriptor does not match last descriptor"));
|
return Ok(NetworkResult::invalid_message(
|
||||||
|
"setvalue descriptor does not match last descriptor",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Descriptor was not provided always go with last descriptor
|
// Descriptor was not provided always go with last descriptor
|
||||||
@ -210,7 +227,9 @@ impl StorageManager {
|
|||||||
descriptor
|
descriptor
|
||||||
} else {
|
} else {
|
||||||
// No descriptor
|
// No descriptor
|
||||||
return Ok(NetworkResult::invalid_message("descriptor must be provided"));
|
return Ok(NetworkResult::invalid_message(
|
||||||
|
"descriptor must be provided",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -228,16 +247,18 @@ impl StorageManager {
|
|||||||
let res = if is_local {
|
let res = if is_local {
|
||||||
inner.handle_set_local_value(key, subkey, value).await
|
inner.handle_set_local_value(key, subkey, value).await
|
||||||
} else {
|
} else {
|
||||||
inner.handle_set_remote_value(key, subkey, value, actual_descriptor).await
|
inner
|
||||||
|
.handle_set_remote_value(key, subkey, value, actual_descriptor)
|
||||||
|
.await
|
||||||
};
|
};
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => {},
|
Ok(()) => {}
|
||||||
Err(VeilidAPIError::Internal { message }) => {
|
Err(VeilidAPIError::Internal { message }) => {
|
||||||
apibail_internal!(message);
|
apibail_internal!(message);
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Ok(NetworkResult::invalid_message(e));
|
return Ok(NetworkResult::invalid_message(e));
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
Ok(NetworkResult::value(None))
|
Ok(NetworkResult::value(None))
|
||||||
}
|
}
|
||||||
|
@ -117,15 +117,15 @@ Future<VeilidConfig> getDefaultVeilidConfig(String programName) async =>
|
|||||||
),
|
),
|
||||||
dht: VeilidConfigDHT(
|
dht: VeilidConfigDHT(
|
||||||
resolveNodeTimeoutMs: 10000,
|
resolveNodeTimeoutMs: 10000,
|
||||||
resolveNodeCount: 20,
|
resolveNodeCount: 1,
|
||||||
resolveNodeFanout: 3,
|
resolveNodeFanout: 4,
|
||||||
maxFindNodeCount: 20,
|
maxFindNodeCount: 20,
|
||||||
getValueTimeoutMs: 10000,
|
getValueTimeoutMs: 10000,
|
||||||
getValueCount: 20,
|
getValueCount: 3,
|
||||||
getValueFanout: 3,
|
getValueFanout: 4,
|
||||||
setValueTimeoutMs: 10000,
|
setValueTimeoutMs: 10000,
|
||||||
setValueCount: 20,
|
setValueCount: 4,
|
||||||
setValueFanout: 5,
|
setValueFanout: 6,
|
||||||
minPeerCount: 20,
|
minPeerCount: 20,
|
||||||
minPeerRefreshTimeMs: 60000,
|
minPeerRefreshTimeMs: 60000,
|
||||||
validateDialInfoReceiptTimeMs: 2000,
|
validateDialInfoReceiptTimeMs: 2000,
|
||||||
|
Loading…
Reference in New Issue
Block a user