Skip to content
Snippets Groups Projects
Unverified Commit cbee7fe1 authored by Timo Kösters's avatar Timo Kösters
Browse files

improvement: deduplicate watchers

parent 06b0c926
No related branches found
No related tags found
No related merge requests found
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
use rusqlite::{Connection, DatabaseName::Main, OptionalExtension}; use rusqlite::{Connection, DatabaseName::Main, OptionalExtension};
use std::{ use std::{
cell::RefCell, cell::RefCell,
collections::HashMap, collections::{hash_map, HashMap},
future::Future, future::Future,
path::{Path, PathBuf}, path::{Path, PathBuf},
pin::Pin, pin::Pin,
sync::Arc, sync::Arc,
}; };
use thread_local::ThreadLocal; use thread_local::ThreadLocal;
use tokio::sync::oneshot::Sender; use tokio::sync::watch;
use tracing::debug; use tracing::debug;
thread_local! { thread_local! {
...@@ -126,7 +126,7 @@ fn flush(self: &Arc<Self>) -> Result<()> { ...@@ -126,7 +126,7 @@ fn flush(self: &Arc<Self>) -> Result<()> {
pub struct SqliteTable { pub struct SqliteTable {
engine: Arc<Engine>, engine: Arc<Engine>,
name: String, name: String,
watchers: RwLock<HashMap<Vec<u8>, Vec<Sender<()>>>>, watchers: RwLock<HashMap<Vec<u8>, (watch::Sender<()>, watch::Receiver<()>)>>,
} }
type TupleOfBytes = (Vec<u8>, Vec<u8>); type TupleOfBytes = (Vec<u8>, Vec<u8>);
...@@ -215,10 +215,8 @@ fn insert(&self, key: &[u8], value: &[u8]) -> Result<()> { ...@@ -215,10 +215,8 @@ fn insert(&self, key: &[u8], value: &[u8]) -> Result<()> {
if !triggered.is_empty() { if !triggered.is_empty() {
let mut watchers = self.watchers.write(); let mut watchers = self.watchers.write();
for prefix in triggered { for prefix in triggered {
if let Some(txs) = watchers.remove(prefix) { if let Some(tx) = watchers.remove(prefix) {
for tx in txs { let _ = tx.0.send(());
let _ = tx.send(());
}
} }
} }
}; };
...@@ -367,17 +365,18 @@ fn scan_prefix<'a>(&'a self, prefix: Vec<u8>) -> Box<dyn Iterator<Item = TupleOf ...@@ -367,17 +365,18 @@ fn scan_prefix<'a>(&'a self, prefix: Vec<u8>) -> Box<dyn Iterator<Item = TupleOf
#[tracing::instrument(skip(self, prefix))] #[tracing::instrument(skip(self, prefix))]
fn watch_prefix<'a>(&'a self, prefix: &[u8]) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { fn watch_prefix<'a>(&'a self, prefix: &[u8]) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
let (tx, rx) = tokio::sync::oneshot::channel(); let mut rx = match self.watchers.write().entry(prefix.to_vec()) {
hash_map::Entry::Occupied(o) => o.get().1.clone(),
self.watchers hash_map::Entry::Vacant(v) => {
.write() let (tx, rx) = tokio::sync::watch::channel(());
.entry(prefix.to_vec()) v.insert((tx, rx.clone()));
.or_default() rx
.push(tx); }
};
Box::pin(async move { Box::pin(async move {
// Tx is never destroyed // Tx is never destroyed
rx.await.unwrap(); rx.changed().await.unwrap();
}) })
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment