mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-19 19:46:50 +00:00
New settings: num_relays_per_person, max_relays (with new relay picker logic)
This commit is contained in:
parent
c8c6fb04af
commit
8e95ccab00
@ -107,7 +107,7 @@ fn upgrade(db: &Connection, mut version: u16) -> Result<(), Error> {
|
|||||||
apply_sql!(db, version, 2, "schema2.sql");
|
apply_sql!(db, version, 2, "schema2.sql");
|
||||||
apply_sql!(db, version, 3, "schema3.sql");
|
apply_sql!(db, version, 3, "schema3.sql");
|
||||||
apply_sql!(db, version, 4, "schema4.sql");
|
apply_sql!(db, version, 4, "schema4.sql");
|
||||||
|
apply_sql!(db, version, 5, "schema5.sql");
|
||||||
info!("Database is at version {}", version);
|
info!("Database is at version {}", version);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
2
src/db/schema5.sql
Normal file
2
src/db/schema5.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
INSERT INTO settings (key, value) values ('num_relays_per_person', '2');
|
||||||
|
INSERT INTO settings (key, value) values ('max_relays', '15');
|
@ -174,16 +174,37 @@ impl Overlord {
|
|||||||
// Pick Relays and start Minions
|
// Pick Relays and start Minions
|
||||||
{
|
{
|
||||||
let pubkeys: Vec<PublicKeyHex> = crate::globals::followed_pubkeys().await;
|
let pubkeys: Vec<PublicKeyHex> = crate::globals::followed_pubkeys().await;
|
||||||
|
let num_relays_per_person = GLOBALS.settings.lock().await.num_relays_per_person;
|
||||||
|
let max_relays = GLOBALS.settings.lock().await.max_relays;
|
||||||
|
let mut pubkey_counts: HashMap<PublicKeyHex, u8> = HashMap::new();
|
||||||
|
for pk in pubkeys.iter() {
|
||||||
|
pubkey_counts.insert(pk.clone(), num_relays_per_person);
|
||||||
|
}
|
||||||
|
|
||||||
let mut relay_picker = RelayPicker {
|
let mut relay_picker = RelayPicker {
|
||||||
relays: all_relays,
|
relays: all_relays,
|
||||||
pubkeys: pubkeys.clone(),
|
pubkey_counts,
|
||||||
person_relays: DbPersonRelay::fetch_for_pubkeys(&pubkeys).await?,
|
person_relays: DbPersonRelay::fetch_for_pubkeys(&pubkeys).await?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut best_relay: BestRelay;
|
let mut best_relay: BestRelay;
|
||||||
|
let mut relay_count = 0;
|
||||||
loop {
|
loop {
|
||||||
|
if relay_count >= max_relays {
|
||||||
|
warn!(
|
||||||
|
"Safety catch: we have picked {} relays. That's enough.",
|
||||||
|
max_relays
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if relay_picker.is_degenerate() {
|
if relay_picker.is_degenerate() {
|
||||||
|
info!(
|
||||||
|
"Relay picker is degenerate, relays={} pubkey_counts={}, person_relays={}",
|
||||||
|
relay_picker.relays.len(),
|
||||||
|
relay_picker.pubkey_counts.len(),
|
||||||
|
relay_picker.person_relays.len()
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +213,7 @@ impl Overlord {
|
|||||||
relay_picker = rp;
|
relay_picker = rp;
|
||||||
|
|
||||||
if best_relay.is_degenerate() {
|
if best_relay.is_degenerate() {
|
||||||
|
info!("Best relay is now degenerate.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,11 +228,15 @@ impl Overlord {
|
|||||||
});
|
});
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Picked relay {}, {} people left",
|
"Picked relay {} covering {} people.",
|
||||||
&best_relay.relay.url,
|
&best_relay.relay.url,
|
||||||
relay_picker.pubkeys.len()
|
best_relay.pubkeys.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
relay_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("Listening on {} relays", relay_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get desired events from relays
|
// Get desired events from relays
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
use crate::db::{DbPersonRelay, DbRelay};
|
use crate::db::{DbPersonRelay, DbRelay};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use nostr_types::PublicKeyHex;
|
use nostr_types::PublicKeyHex;
|
||||||
|
use std::collections::HashMap;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
/// See RelayPicker::best()
|
/// See RelayPicker::best()
|
||||||
pub struct RelayPicker {
|
pub struct RelayPicker {
|
||||||
pub relays: Vec<DbRelay>,
|
pub relays: Vec<DbRelay>,
|
||||||
pub pubkeys: Vec<PublicKeyHex>,
|
pub pubkey_counts: HashMap<PublicKeyHex, u8>,
|
||||||
pub person_relays: Vec<DbPersonRelay>,
|
pub person_relays: Vec<DbPersonRelay>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelayPicker {
|
impl RelayPicker {
|
||||||
pub fn is_degenerate(&self) -> bool {
|
pub fn is_degenerate(&self) -> bool {
|
||||||
self.relays.is_empty() || self.pubkeys.is_empty() || self.person_relays.is_empty()
|
self.relays.is_empty() || self.pubkey_counts.is_empty() || self.person_relays.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function takes a RelayPicker which consists of a list of relays,
|
/// This function takes a RelayPicker which consists of a list of relays,
|
||||||
@ -21,7 +22,7 @@ impl RelayPicker {
|
|||||||
/// the public keys such a relay will cover. It also outpus a new RelayPicker
|
/// the public keys such a relay will cover. It also outpus a new RelayPicker
|
||||||
/// that contains only the remaining relays and public keys.
|
/// that contains only the remaining relays and public keys.
|
||||||
pub fn best(mut self) -> Result<(BestRelay, RelayPicker), Error> {
|
pub fn best(mut self) -> Result<(BestRelay, RelayPicker), Error> {
|
||||||
if self.pubkeys.is_empty() {
|
if self.pubkey_counts.is_empty() {
|
||||||
return Err(Error::General(
|
return Err(Error::General(
|
||||||
"best_relay called for zero people".to_owned(),
|
"best_relay called for zero people".to_owned(),
|
||||||
));
|
));
|
||||||
@ -35,7 +36,7 @@ impl RelayPicker {
|
|||||||
info!(
|
info!(
|
||||||
"Searching for the best relay among {} for {} people",
|
"Searching for the best relay among {} for {} people",
|
||||||
self.relays.len(),
|
self.relays.len(),
|
||||||
self.pubkeys.len()
|
self.pubkey_counts.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Keep score
|
// Keep score
|
||||||
@ -57,7 +58,7 @@ impl RelayPicker {
|
|||||||
// Multiply scores by relay rank
|
// Multiply scores by relay rank
|
||||||
#[allow(clippy::needless_range_loop)]
|
#[allow(clippy::needless_range_loop)]
|
||||||
for i in 0..self.relays.len() {
|
for i in 0..self.relays.len() {
|
||||||
score[i] *= self.relays[i].rank.unwrap_or(1);
|
score[i] *= self.relays[i].rank.unwrap_or(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
let winner_index = score
|
let winner_index = score
|
||||||
@ -76,12 +77,30 @@ impl RelayPicker {
|
|||||||
.map(|x| PublicKeyHex(x.person.clone()))
|
.map(|x| PublicKeyHex(x.person.clone()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.pubkeys.retain(|x| !covered_public_keys.contains(x));
|
// Decrement entries where we found another relay for them
|
||||||
|
let mut changed = false;
|
||||||
|
for (pubkey, count) in self.pubkey_counts.iter_mut() {
|
||||||
|
if covered_public_keys.contains(pubkey) {
|
||||||
|
*count -= 1;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.person_relays.retain(|pr| {
|
// If the pubkey_counts did not change
|
||||||
!covered_public_keys.contains(&PublicKeyHex(pr.person.clone()))
|
if !changed {
|
||||||
&& pr.relay != winner.url
|
// then we are now degenerate.
|
||||||
});
|
// Output a BestRelay with zero public keys to signal this
|
||||||
|
return Ok((
|
||||||
|
BestRelay {
|
||||||
|
relay: winner,
|
||||||
|
pubkeys: vec![],
|
||||||
|
},
|
||||||
|
self,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove entries with 0 more relays needed
|
||||||
|
self.pubkey_counts.retain(|_, v| *v > 0);
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
BestRelay {
|
BestRelay {
|
||||||
|
@ -8,6 +8,8 @@ pub const DEFAULT_AUTOFOLLOW: bool = false;
|
|||||||
pub const DEFAULT_VIEW_POSTS_REFERRED_TO: bool = true;
|
pub const DEFAULT_VIEW_POSTS_REFERRED_TO: bool = true;
|
||||||
pub const DEFAULT_VIEW_POSTS_REFERRING_TO: bool = false;
|
pub const DEFAULT_VIEW_POSTS_REFERRING_TO: bool = false;
|
||||||
pub const DEFAULT_VIEW_THREADED: bool = true;
|
pub const DEFAULT_VIEW_THREADED: bool = true;
|
||||||
|
pub const DEFAULT_NUM_RELAYS_PER_PERSON: u8 = 2;
|
||||||
|
pub const DEFAULT_MAX_RELAYS: u8 = 15;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
@ -19,6 +21,8 @@ pub struct Settings {
|
|||||||
pub view_posts_referred_to: bool,
|
pub view_posts_referred_to: bool,
|
||||||
pub view_posts_referring_to: bool,
|
pub view_posts_referring_to: bool,
|
||||||
pub view_threaded: bool,
|
pub view_threaded: bool,
|
||||||
|
pub num_relays_per_person: u8,
|
||||||
|
pub max_relays: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
@ -30,6 +34,8 @@ impl Default for Settings {
|
|||||||
view_posts_referred_to: DEFAULT_VIEW_POSTS_REFERRED_TO,
|
view_posts_referred_to: DEFAULT_VIEW_POSTS_REFERRED_TO,
|
||||||
view_posts_referring_to: DEFAULT_VIEW_POSTS_REFERRING_TO,
|
view_posts_referring_to: DEFAULT_VIEW_POSTS_REFERRING_TO,
|
||||||
view_threaded: DEFAULT_VIEW_THREADED,
|
view_threaded: DEFAULT_VIEW_THREADED,
|
||||||
|
num_relays_per_person: DEFAULT_NUM_RELAYS_PER_PERSON,
|
||||||
|
max_relays: DEFAULT_MAX_RELAYS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,6 +66,13 @@ impl Settings {
|
|||||||
settings.view_posts_referring_to = numstr_to_bool(row.1)
|
settings.view_posts_referring_to = numstr_to_bool(row.1)
|
||||||
}
|
}
|
||||||
"view_threaded" => settings.view_threaded = numstr_to_bool(row.1),
|
"view_threaded" => settings.view_threaded = numstr_to_bool(row.1),
|
||||||
|
"num_relays_per_person" => {
|
||||||
|
settings.num_relays_per_person =
|
||||||
|
row.1.parse::<u8>().unwrap_or(DEFAULT_NUM_RELAYS_PER_PERSON)
|
||||||
|
}
|
||||||
|
"max_relays" => {
|
||||||
|
settings.max_relays = row.1.parse::<u8>().unwrap_or(DEFAULT_MAX_RELAYS)
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +88,8 @@ impl Settings {
|
|||||||
"REPLACE INTO settings (key, value) VALUES \
|
"REPLACE INTO settings (key, value) VALUES \
|
||||||
('feed_chunk', ?),('overlap', ?),('autofollow', ?),\
|
('feed_chunk', ?),('overlap', ?),('autofollow', ?),\
|
||||||
('view_posts_referred_to', ?),('view_posts_referring_to', ?),\
|
('view_posts_referred_to', ?),('view_posts_referring_to', ?),\
|
||||||
('view_threaded', ?)",
|
('view_threaded', ?),('num_relays_per_person', ?), \
|
||||||
|
('max_relays', ?)",
|
||||||
)?;
|
)?;
|
||||||
stmt.execute((
|
stmt.execute((
|
||||||
self.feed_chunk,
|
self.feed_chunk,
|
||||||
@ -92,6 +106,8 @@ impl Settings {
|
|||||||
"0"
|
"0"
|
||||||
},
|
},
|
||||||
if self.view_threaded { "1" } else { "0" },
|
if self.view_threaded { "1" } else { "0" },
|
||||||
|
self.num_relays_per_person,
|
||||||
|
self.max_relays,
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -16,6 +16,22 @@ pub(super) fn update(
|
|||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
|
ui.add_space(24.0);
|
||||||
|
ui.heading("How Many Relays to Query");
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Number of relays to query per person: ").on_hover_text("We will query N relays per person. Many people share the same relays so those will be queried about multiple people. Takes affect on restart.");
|
||||||
|
ui.add(Slider::new(&mut app.settings.num_relays_per_person, 1..=5).text("relays"));
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Maximum total number of relays to query: ")
|
||||||
|
.on_hover_text(
|
||||||
|
"We will not connect to more than this many relays. Takes affect on restart.",
|
||||||
|
);
|
||||||
|
ui.add(Slider::new(&mut app.settings.max_relays, 1..=30).text("relays"));
|
||||||
|
});
|
||||||
|
|
||||||
ui.add_space(24.0);
|
ui.add_space(24.0);
|
||||||
ui.heading("How Many Posts to Load");
|
ui.heading("How Many Posts to Load");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user