This commit is contained in:
2026-07-27 10:46:10 +07:00
parent 8bbb472103
commit b349656c56
3 changed files with 168 additions and 226 deletions

View File

@@ -1,6 +1,5 @@
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
use std::time::Duration;
use anyhow::{Error, anyhow};
@@ -24,9 +23,9 @@ impl Global for GlobalPersonRegistry {}
#[derive(Debug, Clone)]
enum Dispatch {
Person(Box<Person>),
Announcement(Box<Event>),
Relays(Box<Event>),
Person(Person),
Announcement(Event),
Relays(Event),
}
/// Person Registry
@@ -36,7 +35,7 @@ pub struct PersonRegistry {
persons: HashMap<PublicKey, Entity<Person>>,
/// Set of public keys that have been seen
seens: Rc<RefCell<HashSet<PublicKey>>>,
seens: RefCell<HashSet<PublicKey>>,
/// Sender for requesting metadata
sender: flume::Sender<PublicKey>,
@@ -67,49 +66,38 @@ impl PersonRegistry {
let mut tasks = smallvec![];
tasks.push(
// Handle nostr notifications
cx.background_spawn({
let client = client.clone();
tasks.push(cx.background_spawn({
let client = client.clone();
async move {
Self::handle_notifications(&client, &tx).await;
}
}));
async move {
Self::handle_notifications(&client, &tx).await;
}
}),
);
tasks.push(cx.background_spawn({
let client = client.clone();
async move {
Self::handle_requests(&client, &mta_rx).await;
}
}));
tasks.push(
// Handle metadata requests
cx.background_spawn({
let client = client.clone();
async move {
Self::handle_requests(&client, &mta_rx).await;
}
}),
);
tasks.push(
// Update GPUI state
cx.spawn(async move |this, cx| {
while let Ok(event) = rx.recv_async().await {
this.update(cx, |this, cx| {
match event {
Dispatch::Person(person) => {
this.insert(*person, cx);
}
Dispatch::Announcement(event) => {
this.set_announcement(&event, cx);
}
Dispatch::Relays(event) => {
this.set_messaging_relays(&event, cx);
}
};
})
.ok();
}
}),
);
tasks.push(cx.spawn(async move |this, cx| {
while let Ok(event) = rx.recv_async().await {
this.update(cx, |this, cx| {
match event {
Dispatch::Person(person) => {
this.insert(person, cx);
}
Dispatch::Announcement(event) => {
this.set_announcement(&event, cx);
}
Dispatch::Relays(event) => {
this.set_messaging_relays(&event, cx);
}
};
})
.ok();
}
}));
// Load all user profiles from the database
cx.defer_in(window, |this, _window, cx| {
@@ -118,7 +106,7 @@ impl PersonRegistry {
Self {
persons: HashMap::new(),
seens: Rc::new(RefCell::new(HashSet::new())),
seens: RefCell::new(HashSet::new()),
sender: mta_tx,
tasks,
}
@@ -145,24 +133,25 @@ impl PersonRegistry {
Kind::Metadata => {
let metadata = Metadata::from_json(&event.content).unwrap_or_default();
let person = Person::new(event.pubkey, metadata);
let val = Box::new(person);
// Send
tx.send_async(Dispatch::Person(val)).await.ok();
if tx.send_async(Dispatch::Person(person)).await.is_err() {
log::warn!("PersonRegistry channel closed, dropping metadata event");
}
}
Kind::ContactList => {
let public_keys = event.extract_public_keys();
// Get metadata for all public keys
get_metadata(client, public_keys).await.ok();
if let Err(e) = get_metadata(client, public_keys).await {
log::warn!("Failed to get metadata for contact list: {e}");
}
}
Kind::InboxRelays => {
let val = Box::new(event.into_owned());
// Send
tx.send_async(Dispatch::Relays(val)).await.ok();
tx.send_async(Dispatch::Relays(event.into_owned()))
.await
.ok();
}
Kind::Custom(10044) => {
let val = Box::new(event.into_owned());
// Send
tx.send_async(Dispatch::Announcement(val)).await.ok();
tx.send_async(Dispatch::Announcement(event.into_owned()))
.await
.ok();
}
_ => {}
}
@@ -182,13 +171,17 @@ impl PersonRegistry {
Ok(Some(public_key)) => {
batch.insert(public_key);
// Process the batch if it's full
if batch.len() >= 20 {
get_metadata(client, std::mem::take(&mut batch)).await.ok();
if batch.len() >= 20
&& let Err(e) = get_metadata(client, std::mem::take(&mut batch)).await
{
log::warn!("Failed to get metadata batch: {e}");
}
}
_ => {
if !batch.is_empty() {
get_metadata(client, std::mem::take(&mut batch)).await.ok();
if !batch.is_empty()
&& let Err(e) = get_metadata(client, std::mem::take(&mut batch)).await
{
log::warn!("Failed to get metadata batch: {e}");
}
}
}
@@ -290,15 +283,14 @@ impl PersonRegistry {
}
let public_key = *public_key;
let mut seen = self.seens.borrow_mut();
if seen.insert(public_key) {
if self.seens.borrow_mut().insert(public_key) {
let sender = self.sender.clone();
// Spawn background task to request metadata
cx.background_spawn(async move {
if let Err(e) = sender.send_async(public_key).await {
log::warn!("Failed to send public key for metadata request: {}", e);
log::warn!("Failed to send public key for metadata request: {e}");
}
})
.detach();