Add atomic bulk channel subscription updates (#59998)

## What changed

Add `LocalAgentMessageBoard::set_subscriptions` to apply a caller's subscribe and unsubscribe choices for multiple channels in one transaction. Validate all supplied channels before applying changes, and preserve subscriptions for other channels, threads, and agents.

Allow this self-only operation on read-only live connections, reject fixed views, and emit no notifications. Share subscription and opt-out updates with the existing single-subscription API.

## Testing

Add coverage for bulk updates through a read-only connection, atomic failure when a channel is missing, preservation of other channels and agents, and the absence of notifications.

GitOrigin-RevId: 83ed587f9c5deaa3e9de87adb6319f9de0c804b1
This commit is contained in:
felixxia-oai
2026-11-06 22:09:04 +00:00
committed by copyberry
parent 8d0098930e
commit eb485f57ba
3 changed files with 181 additions and 21 deletions
+3 -21
View File
@@ -52,6 +52,7 @@ mod paging;
mod pool;
mod queries;
pub(crate) mod setup;
mod subscriptions;
#[cfg(test)]
#[path = "local/pools_tests.rs"]
@@ -422,27 +423,8 @@ impl LocalAgentMessageBoard {
.map(Uuid::parse_str)
.transpose()
.map_err(storage_error)?;
// Keep active subscriptions readable by older binaries. Opt-outs only
// prevent implicit subscription when this agent participates again.
let statements = match request.change {
SubscriptionChange::Subscribe => [
"DELETE FROM subscription_opt_outs WHERE board=? AND target=? AND agent=?",
"INSERT OR IGNORE INTO subscriptions(board,target,agent) VALUES(?,?,?)",
],
SubscriptionChange::Unsubscribe => [
"DELETE FROM subscriptions WHERE board=? AND target=? AND agent=?",
"INSERT OR IGNORE INTO subscription_opt_outs(board,target,agent) VALUES(?,?,?)",
],
};
for statement in statements {
sqlx::query(statement)
.bind(self.identity.to_string())
.bind(target_key(&request.target)?)
.bind(target_agent.to_string())
.execute(&mut *tx)
.await
.map_err(storage_error)?;
}
self.change_subscription(&mut tx, &request.target, target_agent, request.change)
.await?;
tx.commit().await.map_err(storage_error)?;
Ok(SubscriptionState {
channel_name: channel,