huskies: merge 726_story_notify_chat_transports_when_oauth_account_swaps_or_all_accounts_are_exhausted
This commit is contained in:
@@ -305,11 +305,17 @@ fn panic_payload_to_string(payload: &Box<dyn std::any::Any + Send>) -> String {
|
||||
/// Spawn a background task that listens for [`WatcherEvent::RateLimitHardBlock`]
|
||||
/// events and auto-schedules a timer for the blocked story.
|
||||
///
|
||||
/// When an OAuth account swap succeeds, emits [`WatcherEvent::OAuthAccountSwapped`]
|
||||
/// so chat transports can notify the user which account took over. When all
|
||||
/// accounts are exhausted, emits [`WatcherEvent::OAuthAccountsExhausted`] with
|
||||
/// the earliest reset time.
|
||||
///
|
||||
/// If a timer already exists for the story, it is updated to the later reset time
|
||||
/// rather than creating a duplicate (via [`TimerStore::upsert`]).
|
||||
pub fn spawn_rate_limit_auto_scheduler(
|
||||
store: Arc<TimerStore>,
|
||||
mut watcher_rx: tokio::sync::broadcast::Receiver<crate::io::watcher::WatcherEvent>,
|
||||
watcher_tx: tokio::sync::broadcast::Sender<crate::io::watcher::WatcherEvent>,
|
||||
) {
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
@@ -344,6 +350,9 @@ pub fn spawn_rate_limit_auto_scheduler(
|
||||
(agent {agent_name}): now using '{new_email}'. \
|
||||
Auto-assign will restart the agent with the new account."
|
||||
);
|
||||
let _ = watcher_tx.send(
|
||||
crate::io::watcher::WatcherEvent::OAuthAccountSwapped { new_email },
|
||||
);
|
||||
// No timer needed — auto-assign picks up the story.
|
||||
continue;
|
||||
}
|
||||
@@ -352,6 +361,14 @@ pub fn spawn_rate_limit_auto_scheduler(
|
||||
"[timer] Account swap not possible for story {story_id}: \
|
||||
{swap_err}. Falling back to timer-based retry."
|
||||
);
|
||||
// Notify chat transports when all accounts are exhausted.
|
||||
if swap_err.contains("All OAuth accounts are rate-limited") {
|
||||
let _ = watcher_tx.send(
|
||||
crate::io::watcher::WatcherEvent::OAuthAccountsExhausted {
|
||||
earliest_reset_msg: swap_err.clone(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,7 +578,7 @@ mod tests {
|
||||
let store = Arc::new(TimerStore::load(dir.path().join("timers.json")));
|
||||
let (watcher_tx, watcher_rx) = tokio::sync::broadcast::channel::<WatcherEvent>(16);
|
||||
|
||||
spawn_rate_limit_auto_scheduler(Arc::clone(&store), watcher_rx);
|
||||
spawn_rate_limit_auto_scheduler(Arc::clone(&store), watcher_rx, watcher_tx.clone());
|
||||
|
||||
let reset_at = Utc::now() + Duration::hours(1);
|
||||
watcher_tx
|
||||
@@ -591,7 +608,7 @@ mod tests {
|
||||
let store = Arc::new(TimerStore::load(dir.path().join("timers.json")));
|
||||
let (watcher_tx, watcher_rx) = tokio::sync::broadcast::channel::<WatcherEvent>(16);
|
||||
|
||||
spawn_rate_limit_auto_scheduler(Arc::clone(&store), watcher_rx);
|
||||
spawn_rate_limit_auto_scheduler(Arc::clone(&store), watcher_rx, watcher_tx.clone());
|
||||
|
||||
let first = Utc::now() + Duration::hours(1);
|
||||
let second = Utc::now() + Duration::hours(2);
|
||||
|
||||
Reference in New Issue
Block a user