pub struct ClientBlocking(/* private fields */);Expand description
A blocking (synchronous) version of Client.
Implementations§
Source§impl ClientBlocking
impl ClientBlocking
Sourcepub fn dht(&self) -> Option<Dht>
pub fn dht(&self) -> Option<Dht>
Returns a reference to the internal mainline::Dht node.
Gives you access to methods like mainline::Dht::info, mainline::Dht::bootstrapped, and mainline::Dht::to_bootstrap among the rest of the API.
Sourcepub fn publish(
&self,
signed_packet: &SignedPacket,
cas: Option<Timestamp>,
) -> Result<(), PublishError>
pub fn publish( &self, signed_packet: &SignedPacket, cas: Option<Timestamp>, ) -> Result<(), PublishError>
Publishes a SignedPacket to the mainline Dht and or Relays.
§Lost Update Problem
Mainline DHT and remote relays form a distributed network, and like all distributed networks, it is vulnerable to Write–write conflict.
§Read first
To mitigate the risk of lost updates, you should call the Self::resolve_most_recent method then start authoring the new SignedPacket based on the most recent as in the following example:
use pkarr::{Client, SignedPacket, Keypair};
// For local testing
use pkarr::mainline::Testnet;
fn run() -> anyhow::Result<()> {
let testnet = Testnet::new(3)?;
let client = Client::builder()
// Disable the default network settings (builtin relays and mainline bootstrap nodes).
.no_default_network()
.bootstrap(&testnet.bootstrap)
.build()?
.as_blocking();
let keypair = Keypair::random();
let (signed_packet, cas) = if let Some(most_recent) = client
.resolve_most_recent(&keypair.public_key())
{
let mut builder = SignedPacket::builder();
// 1. Optionally inherit all or some of the existing records.
for record in most_recent.all_resource_records() {
let name = record.name.to_string();
if name != "foo" && name != "sercert" {
builder = builder.record(record.clone());
}
};
// 2. Optionally add more new records.
let signed_packet = builder
.txt("foo".try_into()?, "bar".try_into()?, 30)
.a("secret".try_into()?, 42.into(), 30)
.sign(&keypair)?;
(
signed_packet,
// 3. Use the most recent [SignedPacket::timestamp] as a `CAS`.
Some(most_recent.timestamp())
)
} else {
(
SignedPacket::builder()
.txt("foo".try_into()?, "bar".try_into()?, 30)
.a("secret".try_into()?, 42.into(), 30)
.sign(&keypair)?,
None
)
};
client.publish(&signed_packet, cas)?;
Ok(())
}§Errors
This method may return on of these errors:
- super::QueryError: when the query fails, and you need to retry or debug the network.
- super::ConcurrencyError: when an write conflict (or the risk of it) is detedcted.
If you get a super::ConcurrencyError; you should resolver the most recent packet again, and repeat the steps in the previous example.
Sourcepub fn resolve(&self, public_key: &PublicKey) -> Option<SignedPacket>
pub fn resolve(&self, public_key: &PublicKey) -> Option<SignedPacket>
Returns a SignedPacket from the cache even if it is expired. If there is no packet in the cache, or if the cached packet is expired, it will make a DHT query in a background query and caches any more recent packets it receives.
If you want to get the most recent version of a SignedPacket, you should use Self::resolve_most_recent.
Sourcepub fn resolve_most_recent(
&self,
public_key: &PublicKey,
) -> Option<SignedPacket>
pub fn resolve_most_recent( &self, public_key: &PublicKey, ) -> Option<SignedPacket>
Returns the most recent SignedPacket found after querying all mainline Dht nodes and or Relays.
Useful if you want to read the most recent packet before publishing a new packet.
This is a best effort, and doesn’t guarantee consistency.
Trait Implementations§
Source§impl Clone for ClientBlocking
impl Clone for ClientBlocking
Source§fn clone(&self) -> ClientBlocking
fn clone(&self) -> ClientBlocking
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more