fix: cleanup database connections with same name

When a large number of subscriptions is created with identical names,
we do not send a signal over the abandon-read channel.  This
eventually leads to resource exhaustion.
This commit is contained in:
Greg Heartsfield 2022-01-30 15:14:02 -06:00
parent 6502f7dcd7
commit 4cc313fa2d

View File

@ -280,7 +280,6 @@ async fn nostr_server(
// maintain a hashmap of a oneshot channel for active subscriptions. // maintain a hashmap of a oneshot channel for active subscriptions.
// when these subscriptions are cancelled, make a message // when these subscriptions are cancelled, make a message
// available to the executing query so it knows to stop. // available to the executing query so it knows to stop.
//let (abandon_query_tx, _) = oneshot::channel::<()>();
let mut running_queries: HashMap<String, oneshot::Sender<()>> = HashMap::new(); let mut running_queries: HashMap<String, oneshot::Sender<()>> = HashMap::new();
// for stats, keep track of how many events the client published, // for stats, keep track of how many events the client published,
// and how many it received from queries. // and how many it received from queries.
@ -348,7 +347,10 @@ async fn nostr_server(
let (abandon_query_tx, abandon_query_rx) = oneshot::channel::<()>(); let (abandon_query_tx, abandon_query_rx) = oneshot::channel::<()>();
match conn.subscribe(s.clone()) { match conn.subscribe(s.clone()) {
Ok(()) => { Ok(()) => {
running_queries.insert(s.id.to_owned(), abandon_query_tx); // when we insert, if there was a previous query running with the same name, cancel it.
if let Some(previous_query) = running_queries.insert(s.id.to_owned(), abandon_query_tx) {
previous_query.send(()).ok();
}
// start a database query // start a database query
// show pool stats // show pool stats
debug!("DB pool stats: {:?}", pool.state()); debug!("DB pool stats: {:?}", pool.state());