-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Add dispatcher and task modules
- Loading branch information
Showing
4 changed files
with
198 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use futures::channel::mpsc; | ||
use std::collections::HashMap; | ||
use std::error::Error; | ||
use std::fmt; | ||
use uuid::Uuid; | ||
|
||
use nostrdb::Filter; | ||
|
||
use crate::Damus; | ||
|
||
#[allow(dead_code)] // until InternalError is used | ||
#[derive(Debug)] | ||
pub enum DispatcherError { | ||
InternalError(String), | ||
} | ||
|
||
impl fmt::Display for DispatcherError { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
match self { | ||
DispatcherError::InternalError(msg) => write!(f, "Internal error: {}", msg), | ||
} | ||
} | ||
} | ||
|
||
impl Error for DispatcherError {} | ||
|
||
pub type DispatcherResult<T> = Result<T, DispatcherError>; | ||
|
||
#[derive(Debug)] | ||
pub enum Event { | ||
Pool, | ||
} | ||
|
||
/// Used by the relay code to dispatch events to a waiting handlers | ||
#[derive(Debug, Clone)] | ||
pub struct SubscriptionHandler { | ||
pub sender: mpsc::Sender<Event>, | ||
} | ||
|
||
/// Maps subscription id to handler for the subscription | ||
pub type HandlerTable = HashMap<String, SubscriptionHandler>; | ||
|
||
/// Used by async tasks to receive events | ||
#[allow(dead_code)] // until id is read | ||
#[derive(Debug)] | ||
pub struct Subscription { | ||
pub id: String, | ||
pub receiver: mpsc::Receiver<Event>, | ||
} | ||
|
||
pub fn subscribe( | ||
damus: &mut Damus, | ||
filters: &[Filter], | ||
bufsz: usize, | ||
) -> DispatcherResult<Subscription> { | ||
let (sender, receiver) = mpsc::channel::<Event>(bufsz); | ||
let id = Uuid::new_v4().to_string(); | ||
damus | ||
.dispatch | ||
.insert(id.clone(), SubscriptionHandler { sender }); | ||
damus.pool.subscribe(id.clone(), filters.into()); | ||
Ok(Subscription { id, receiver }) | ||
} | ||
|
||
pub fn _unsubscribe(_sub: Subscription) -> DispatcherResult<()> { | ||
unimplemented!() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
use futures::stream::StreamExt; | ||
use tracing::{debug, error}; | ||
|
||
use enostr::RelayPool; | ||
use nostrdb::{Filter, Ndb, Transaction}; | ||
|
||
use crate::dispatcher; | ||
use crate::note::NoteRef; | ||
use crate::{with_mut_damus, DamusRef}; | ||
|
||
pub async fn setup_user_relays(damusref: DamusRef) { | ||
debug!("do_setup_user_relays starting"); | ||
|
||
let filter = with_mut_damus(&damusref, |damus| { | ||
debug!("setup_user_relays: acquired damus for filter"); | ||
|
||
let account = damus | ||
.accounts | ||
.get_selected_account() | ||
.as_ref() | ||
.map(|a| a.pubkey.bytes()) | ||
.expect("selected account"); | ||
|
||
// NIP-65 | ||
Filter::new() | ||
.authors([account]) | ||
.kinds([10002]) | ||
.limit(1) | ||
.build() | ||
}); | ||
|
||
let mut sub = with_mut_damus(&damusref, |damus| { | ||
debug!("setup_user_relays: acquired damus for query + subscribe"); | ||
let txn = Transaction::new(&damus.ndb).expect("transaction"); | ||
let relays = query_nip65_relays(&damus.ndb, &txn, &filter); | ||
debug!("setup_user_relays: query #1 relays: {:#?}", relays); | ||
add_relays(&mut damus.pool, relays); | ||
|
||
// Add a relay subscription to the pool | ||
dispatcher::subscribe(damus, &[filter.clone()], 10).expect("subscribe") | ||
}); | ||
debug!("setup_user_relays: sub {}", sub.id); | ||
|
||
loop { | ||
match sub.receiver.next().await { | ||
Some(ev) => { | ||
debug!("setup_user_relays: saw {:?}", ev); | ||
with_mut_damus(&damusref, |damus| { | ||
let txn = Transaction::new(&damus.ndb).expect("transaction"); | ||
let relays = query_nip65_relays(&damus.ndb, &txn, &filter); | ||
debug!("setup_user_relays: query #2 relays: {:#?}", relays); | ||
add_relays(&mut damus.pool, relays); | ||
}) | ||
} | ||
None => { | ||
debug!("setup_user_relays: saw None"); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
debug!("do_setup_user_relays finished"); | ||
} | ||
|
||
fn _query_note_json(ndb: &Ndb, txn: &Transaction, filter: &Filter) -> Vec<String> { | ||
let lim = filter.limit().unwrap_or(crate::filter::default_limit()) as i32; | ||
let results = ndb | ||
.query(txn, &[filter.clone()], lim) | ||
.expect("query results"); | ||
results | ||
.iter() | ||
.map(|qr| NoteRef::new(qr.note_key, qr.note.created_at())) | ||
.filter_map(|nr| ndb.get_note_by_key(txn, nr.key).ok()) | ||
.map(|n| n.json().unwrap()) | ||
.collect() | ||
} | ||
|
||
fn query_nip65_relays(ndb: &Ndb, txn: &Transaction, filter: &Filter) -> Vec<String> { | ||
let lim = filter.limit().unwrap_or(crate::filter::default_limit()) as i32; | ||
let results = ndb | ||
.query(txn, &[filter.clone()], lim) | ||
.expect("query results"); | ||
results | ||
.iter() | ||
.map(|qr| NoteRef::new(qr.note_key, qr.note.created_at())) | ||
.filter_map(|nr| ndb.get_note_by_key(txn, nr.key).ok()) | ||
.flat_map(|n| { | ||
n.tags() | ||
.iter() | ||
.filter_map(|ti| ti.get_unchecked(1).variant().str()) | ||
.map(|s| s.to_string()) | ||
}) | ||
.collect() | ||
} | ||
|
||
fn add_relays(pool: &mut RelayPool, relays: Vec<String>) { | ||
let wakeup = move || { | ||
// FIXME - how do we repaint? | ||
}; | ||
for relay in relays { | ||
if let Err(e) = pool.add_url(relay, wakeup.clone()) { | ||
Check failure on line 101 in src/task.rs GitHub Actions / Clippy
|
||
error!("{:?}", e) | ||
} | ||
} | ||
} |