Skip to content

Commit

Permalink
feat: add resolver option to make cold starts faster
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuhvi committed Apr 24, 2024
1 parent 9af9080 commit eead32a
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 108 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pkarr/examples/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use pkarr::{dns, Keypair, PkarrClient, Result, SignedPacket};

fn main() -> Result<()> {
tracing_subscriber::fmt()
// Switch to DEBUG to see incoming values and the IP of the responding nodes
.with_max_level(Level::DEBUG)
.init();

Expand Down
7 changes: 1 addition & 6 deletions pkarr/examples/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ struct Cli {

fn main() {
tracing_subscriber::fmt()
// Switch to DEBUG to see incoming values and the IP of the responding nodes
.with_max_level(Level::DEBUG)
.with_env_filter("pkarr")
.init();
Expand All @@ -37,11 +36,7 @@ fn main() {
.try_into()
.expect("Invalid zbase32 encoded key");

let client = PkarrClient::builder()
// .minimum_ttl(0)
// .maximum_ttl(5)
.build()
.unwrap();
let client = PkarrClient::builder().build().unwrap();

println!("Resolving Pkarr: {} ...", cli.public_key);
println!("\n=== COLD LOOKUP ===");
Expand Down
28 changes: 28 additions & 0 deletions pkarr/examples/resolver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! This example shows how to run a resolver node.
use std::num::NonZeroUsize;

use tracing::Level;
use tracing_subscriber;

use pkarr::{PkarrClient, Result};

fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_max_level(Level::DEBUG)
.with_env_filter("pkarr")
.init();

let client = PkarrClient::builder()
.resolver()
.cache_size(NonZeroUsize::new(1000).unwrap())
.build()
.unwrap();

println!(
"\nRunning a resolver at {} ...\n",
client.loca_addr().unwrap()
);

loop {}
}
21 changes: 10 additions & 11 deletions pkarr/src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,49 @@
use lru::LruCache;
use mainline::Id;
use std::num::NonZeroUsize;
use std::sync::{Arc, Mutex};

use crate::{PublicKey, SignedPacket};
use crate::SignedPacket;

/// A wrapper around `LruCache`. This struct is thread safe, doesn't return any references to any
/// elements inside.
#[derive(Debug, Clone)]
pub struct PkarrCache {
inner: Arc<Mutex<LruCache<PublicKey, SignedPacket>>>,
inner: Arc<Mutex<LruCache<Id, SignedPacket>>>,
}

impl PkarrCache {
/// Creats a new `LRU` cache that holds at most `cap` items.
pub fn new(cap: NonZeroUsize) -> Self {
pub fn new(capacity: NonZeroUsize) -> Self {
Self {
inner: Arc::new(Mutex::new(LruCache::new(cap))),
inner: Arc::new(Mutex::new(LruCache::new(capacity))),
}
}

/// Puts [SignedPacket], if a version of the packet already exists,
/// and it has the same [SignedPacket::as_bytes], then only [SignedPacket::last_seen] will be
/// updated, otherwise the input will be cloned.
pub fn put(&self, signed_packet: &SignedPacket) {
pub fn put(&self, target: &Id, signed_packet: &SignedPacket) {
let mut lock = self.inner.lock().unwrap();

let public_key = signed_packet.public_key();

match lock.get_mut(&public_key) {
match lock.get_mut(target) {
Some(existing) => {
if existing.as_bytes() == signed_packet.as_bytes() {
// just refresh the last_seen
existing.set_last_seen(signed_packet.last_seen())
} else {
lock.put(public_key, signed_packet.clone());
lock.put(*target, signed_packet.clone());
}
}
None => {
lock.put(public_key, signed_packet.clone());
lock.put(*target, signed_packet.clone());
}
}
}

/// Returns the [SignedPacket] for the public_key in the cache or None if it is not present in the cache.
/// Moves the key to the head of the LRU list if it exists.
pub fn get(&self, public_key: &PublicKey) -> Option<SignedPacket> {
pub fn get(&self, public_key: &Id) -> Option<SignedPacket> {
self.inner.lock().unwrap().get(public_key).cloned()
}
}
Loading

0 comments on commit eead32a

Please sign in to comment.