diff --git a/constellation/templates/dids.html.j2 b/constellation/templates/dids.html.j2
index f694428..49ec6ed 100644
--- a/constellation/templates/dids.html.j2
+++ b/constellation/templates/dids.html.j2
@@ -27,7 +27,7 @@
{% for did in linking_dids %}
DID: {{ did.0 }}
-> see links to this DID
- -> browse this DID record
+ -> browse this DID record
{% endfor %}
{% if let Some(c) = cursor %}
--
2.51.2
From 7b82218085d42d873610dbfc567ce46271258428 Mon Sep 17 00:00:00 2001
From: phil
Date: Thu, 8 Jan 2026 17:27:09 -0500
Subject: [PATCH 2/4] spacedust: add subject prefix filtering
---
Cargo.lock | 4 ++--
spacedust/src/error.rs | 2 ++
spacedust/src/server.rs | 13 +++++++++++--
spacedust/src/subscriber.rs | 11 ++++++++++-
4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 41e7296..dde2d00 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1796,7 +1796,7 @@ dependencies = [
[[package]]
name = "fjall"
version = "2.11.2"
-source = "git+https://github.com/fjall-rs/fjall.git#42d811f7c8cc9004407d520d37d2a1d8d246c03d"
+source = "git+https://github.com/fjall-rs/fjall.git?rev=fb229572bb7d1d6966a596994dc1708e47ec57d8#fb229572bb7d1d6966a596994dc1708e47ec57d8"
dependencies = [
"byteorder",
"byteview",
@@ -6049,7 +6049,7 @@ dependencies = [
"clap",
"dropshot",
"env_logger",
- "fjall 2.11.2 (git+https://github.com/fjall-rs/fjall.git)",
+ "fjall 2.11.2 (git+https://github.com/fjall-rs/fjall.git?rev=fb229572bb7d1d6966a596994dc1708e47ec57d8)",
"getrandom 0.3.3",
"http",
"jetstream",
diff --git a/spacedust/src/error.rs b/spacedust/src/error.rs
index cbfe445..dac4388 100644
--- a/spacedust/src/error.rs
+++ b/spacedust/src/error.rs
@@ -30,6 +30,8 @@ pub enum SubscriberUpdateError {
TooManySourcesWanted,
#[error("more wantedSubjectDids were requested than allowed (max 10,000)")]
TooManyDidsWanted,
+ #[error("more wantedSubjectPrefixes were requested than allowed (max 100)")]
+ TooManySubjectPrefixesWanted,
#[error("more wantedSubjects were requested than allowed (max 50,000)")]
TooManySubjectsWanted,
}
diff --git a/spacedust/src/server.rs b/spacedust/src/server.rs
index 9d3dcf6..f38d2ce 100644
--- a/spacedust/src/server.rs
+++ b/spacedust/src/server.rs
@@ -227,6 +227,8 @@ pub struct MultiSubscribeQuery {
#[serde(default)]
pub wanted_subjects: HashSet,
#[serde(default)]
+ pub wanted_subject_prefixes: HashSet,
+ #[serde(default)]
pub wanted_subject_dids: HashSet,
#[serde(default)]
pub wanted_sources: HashSet,
@@ -241,12 +243,19 @@ struct MultiSubscribeQueryForDocs {
///
/// The at-uri must be url-encoded
///
- /// Pass this parameter multiple times to specify multiple collections, like
+ /// Pass this parameter multiple times to specify multiple subjects, like
/// `wantedSubjects=[...]&wantedSubjects=[...]`
pub wanted_subjects: String,
+ /// One or more at-uri, URI, or DID prefixes to receive links about
+ ///
+ /// The uri must be url-encoded
+ ///
+ /// Pass this parameter multiple times to specify multiple prefixes, like
+ /// `wantedSubjectPrefixes=[...]&wantedSubjectPrefixes=[...]`
+ pub wanted_subject_prefixes: String,
/// One or more DIDs to receive links about
///
- /// Pass this parameter multiple times to specify multiple collections
+ /// Pass this parameter multiple times to specify multiple subjects
pub wanted_subject_dids: String,
/// One or more link sources to receive links about
///
diff --git a/spacedust/src/subscriber.rs b/spacedust/src/subscriber.rs
index 927ef25..36307c2 100644
--- a/spacedust/src/subscriber.rs
+++ b/spacedust/src/subscriber.rs
@@ -124,8 +124,14 @@ impl Subscriber {
let query = &self.query;
// subject + subject DIDs are logical OR
- if !(query.wanted_subjects.is_empty() && query.wanted_subject_dids.is_empty()
+ if !(query.wanted_subjects.is_empty()
+ && query.wanted_subject_prefixes.is_empty()
+ && query.wanted_subject_dids.is_empty()
|| query.wanted_subjects.contains(&properties.subject)
+ || query
+ .wanted_subject_prefixes
+ .iter()
+ .any(|p| properties.subject.starts_with(p))
|| properties
.subject_did
.as_ref()
@@ -155,6 +161,9 @@ impl MultiSubscribeQuery {
if opts.wanted_subject_dids.len() > 10_000 {
return Err(SubscriberUpdateError::TooManyDidsWanted);
}
+ if opts.wanted_subject_prefixes.len() > 100 {
+ return Err(SubscriberUpdateError::TooManySubjectPrefixesWanted);
+ }
if opts.wanted_subjects.len() > 50_000 {
return Err(SubscriberUpdateError::TooManySubjectsWanted);
}
--
2.51.2
From c4480e1084aa20e45621213765887ba6a0b155e2 Mon Sep 17 00:00:00 2001
From: mxngls
Date: Sat, 13 Dec 2025 21:57:00 +0900
Subject: [PATCH 3/4] Make metrics collection opt-in
Adds a new --collect-metrics (presence) flag to make metrics collection
opt-in. The new default is to __not__ collect any metrics, i.e. neither
spawning the monitoring thread nor starting the metrics server server
that exposes these.
---
constellation/src/bin/main.rs | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/constellation/src/bin/main.rs b/constellation/src/bin/main.rs
index c602d85..52cfc0f 100644
--- a/constellation/src/bin/main.rs
+++ b/constellation/src/bin/main.rs
@@ -26,6 +26,10 @@ struct Args {
#[arg(long)]
#[clap(default_value = "0.0.0.0:6789")]
bind: SocketAddr,
+ /// optionally disable the metrics server
+ #[arg(long)]
+ #[clap(default_value_t = false)]
+ collect_metrics: bool,
/// metrics server's listen address
#[arg(long)]
#[clap(default_value = "0.0.0.0:8765")]
@@ -92,6 +96,7 @@ fn main() -> Result<()> {
let bind = args.bind;
let metrics_bind = args.bind_metrics;
+ let collect_metrics = args.collect_metrics;
let stay_alive = CancellationToken::new();
match args.backend {
@@ -102,6 +107,7 @@ fn main() -> Result<()> {
stream,
bind,
metrics_bind,
+ collect_metrics,
stay_alive,
),
#[cfg(feature = "rocks")]
@@ -136,6 +142,7 @@ fn main() -> Result<()> {
stream,
bind,
metrics_bind,
+ collect_metrics,
stay_alive,
);
eprintln!("run finished: {r:?}");
@@ -147,6 +154,8 @@ fn main() -> Result<()> {
}
}
+#[allow(clippy::too_many_lines)]
+#[allow(clippy::too_many_arguments)]
fn run(
mut storage: impl LinkStorage,
fixture: Option,
@@ -154,6 +163,7 @@ fn run(
stream: String,
bind: SocketAddr,
metrics_bind: SocketAddr,
+ collect_metrics: bool,
stay_alive: CancellationToken,
) -> Result<()> {
ctrlc::set_handler({
@@ -198,7 +208,10 @@ fn run(
.build()
.expect("axum startup")
.block_on(async {
- install_metrics_server(metrics_bind)?;
+ // Install metrics server only if requested
+ if collect_metrics {
+ install_metrics_server(metrics_bind)?;
+ }
serve(readable, bind, staying_alive).await
})
.unwrap();
@@ -206,7 +219,9 @@ fn run(
}
});
- s.spawn(move || { // monitor thread
+ // only spawn monitoring thread if the metrics server is running
+ if collect_metrics {
+ s.spawn(move || { // monitor thread
let stay_alive = stay_alive.clone();
let check_alive = stay_alive.clone();
@@ -258,7 +273,8 @@ fn run(
}
}
stay_alive.drop_guard();
- });
+ });
+ }
});
println!("byeeee");
--
2.51.2
From d55f39c1dd19a6435f1f0f78fb264a14c2565c6f Mon Sep 17 00:00:00 2001
From: mxngls
Date: Mon, 15 Dec 2025 15:31:11 +0100
Subject: [PATCH 4/4] Increase constellation response limits
As outlined in the description of issue #4 we increase:
- the default response limit from 16 to __100__
- the maximum from 100 to __1000_
---
constellation/src/server/mod.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/constellation/src/server/mod.rs b/constellation/src/server/mod.rs
index 9c3d1ad..6ca2429 100644
--- a/constellation/src/server/mod.rs
+++ b/constellation/src/server/mod.rs
@@ -25,8 +25,8 @@ mod filters;
use acceptable::{acceptable, ExtractAccept};
-const DEFAULT_CURSOR_LIMIT: u64 = 16;
-const DEFAULT_CURSOR_LIMIT_MAX: u64 = 100;
+const DEFAULT_CURSOR_LIMIT: u64 = 100;
+const DEFAULT_CURSOR_LIMIT_MAX: u64 = 1000;
fn get_default_cursor_limit() -> u64 {
DEFAULT_CURSOR_LIMIT