~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

Spaces are listed one at a time for each account

Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/discover-one-at-a-time
crates/knotless-serve/src/lib.rs+12−0
@@ -171,6 +171,11 @@ pub struct App {
/// records: a space's records take no compare and swap, so two changes
/// at once would each write over the other.
orgs: Mutex<HashMap<String, Shared<()>>>,
/// One lock per account, held while its spaces are listed
/// ([`spaces::discover`]): two listings at once could each keep what
/// the other's authority said after it, a removal undone by an answer
/// asked before it.
discovers: Mutex<HashMap<String, Shared<()>>>,
}
type Shared<T> = Arc<tokio::sync::Mutex<T>>;
@@ -282,6 +287,7 @@ impl App {
ios_minimum: None,
live: live::Live::default(),
orgs: Mutex::default(),
discovers: Mutex::default(),
})
}
@@ -304,6 +310,12 @@ impl App {
orgs.entry(org.to_string()).or_default().clone()
}
/// The lock held while `did`'s spaces are listed.
pub(crate) fn discover_lock(&self, did: &str) -> Shared<()> {
let mut discovers = self.discovers.lock().unwrap();
discovers.entry(did.to_string()).or_default().clone()
}
/// Whether `did`'s PDS has spaces, for private repositories: unknown
/// until their spaces are first listed ([`spaces::discover`]).
pub fn has_spaces(&self, did: &str) -> Option<bool> {
crates/knotless-serve/src/spaces.rs+5−1
@@ -261,7 +261,9 @@ pub const DISCOVER: Duration = Duration::from_secs(60);
/// ([`Index::maybe_member`]) is asked of its authority as them, so the
/// repositories shared with them are listed to them before they open one,
/// and no longer once they are refused. In the background, at most once
/// every [`DISCOVER`], so whoever looks never waits on it.
/// every [`DISCOVER`], so whoever looks never waits on it, and one at a
/// time for each account, so that an answer asked before a removal is
/// never kept after one asked since.
pub fn discover(app: &Arc<App>, did: &str) {
let Some(index) = app.spaces.clone().filter(|_| app.discovering(did)) else {
return;
@@ -276,6 +278,8 @@ pub fn discover(app: &Arc<App>, did: &str) {
/// [`discover`], waited on.
async fn owned(app: &App, index: &Index, did: &str) -> Result<()> {
let lock = app.discover_lock(did);
let _held = lock.lock().await;
let ctx = crate::login::ctx_for(app, did);
let me = knotless::session::me(&ctx).await?;
let followed: HashSet<String> = index.spaces()?.into_iter().map(|(uri, _)| uri).collect();