feat(dashboard): repost status immediately on first render after restart

The 15s x2 edit-retry-before-repost policy is meant for transient blips during
steady-state operation, not the moment right after a (re)start. On the first
render after startup, use 0 retries: still edit the stored message in place if
possible, but if that edit fails, repost a fresh status message immediately
instead of waiting through the retry cycle. Subsequent ticks use the 2-retry
policy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-08-21 12:34:34 +09:00
parent cf6d1f89fc
commit 9108174380

View File

@@ -808,6 +808,10 @@ export async function startUnifiedDashboard(
const isRenderer = opts.serviceAgentType === 'claude-code'; const isRenderer = opts.serviceAgentType === 'claude-code';
const statusJid = `dc:${opts.statusChannelId}`; const statusJid = `dc:${opts.statusChannelId}`;
// The first render after a (re)start should show the status message
// immediately: edit the stored message if possible, but if that edit fails,
// repost right away instead of waiting through the steady-state retry cycle.
let firstStatusRender = true;
if (isRenderer) { if (isRenderer) {
statusMessageId = readDashboardStatusMessageId(opts.statusChannelId); statusMessageId = readDashboardStatusMessageId(opts.statusChannelId);
} }
@@ -869,9 +873,12 @@ export async function startUnifiedDashboard(
// times with a delay first; only give up (and repost) if all fail. // times with a delay first; only give up (and repost) if all fail.
const editId = statusMessageId; const editId = statusMessageId;
const editMessage = channel.editMessage; const editMessage = channel.editMessage;
// First render after start: 0 retries → repost immediately if the edit
// fails. Steady state: retry twice at 15s before reposting.
const maxRetries = firstStatusRender ? 0 : STATUS_EDIT_MAX_RETRIES;
const edited = await editStatusMessageWithRetry({ const edited = await editStatusMessageWithRetry({
editOnce: () => editMessage(statusJid, editId, content), editOnce: () => editMessage(statusJid, editId, content),
maxRetries: STATUS_EDIT_MAX_RETRIES, maxRetries,
retryDelayMs: STATUS_EDIT_RETRY_DELAY_MS, retryDelayMs: STATUS_EDIT_RETRY_DELAY_MS,
onAttemptFailed: (attempt, willRetry, err) => onAttemptFailed: (attempt, willRetry, err) =>
logger.warn( logger.warn(
@@ -879,7 +886,7 @@ export async function startUnifiedDashboard(
err, err,
messageId: editId, messageId: editId,
attempt, attempt,
maxAttempts: STATUS_EDIT_MAX_RETRIES + 1, maxAttempts: maxRetries + 1,
willRetry, willRetry,
}, },
willRetry willRetry
@@ -901,6 +908,9 @@ export async function startUnifiedDashboard(
writeDashboardStatusMessageId(opts.statusChannelId, id); writeDashboardStatusMessageId(opts.statusChannelId, id);
} }
} }
// A render (edit or repost) happened this tick; subsequent ticks use the
// steady-state retry policy.
firstStatusRender = false;
if (statusMessageId) { if (statusMessageId) {
await cleanupDashboardDuplicateMessages(opts, statusMessageId); await cleanupDashboardDuplicateMessages(opts, statusMessageId);
} }