updateLastTurnSummary writes the cached sidebar summary for a chat. Callers should pass a detached context because this method is used for best-effort background cache writes.
( ctx context.Context, chat database.Chat, expectedUpdatedAt time.Time, summary string, logger slog.Logger, )
| 9788 | // Callers should pass a detached context because this method is used for |
| 9789 | // best-effort background cache writes. |
| 9790 | func (p *Server) updateLastTurnSummary( |
| 9791 | ctx context.Context, |
| 9792 | chat database.Chat, |
| 9793 | expectedUpdatedAt time.Time, |
| 9794 | summary string, |
| 9795 | logger slog.Logger, |
| 9796 | ) { |
| 9797 | summary = strings.TrimSpace(summary) |
| 9798 | lastTurnSummary := sql.NullString{String: summary, Valid: summary != ""} |
| 9799 | |
| 9800 | //nolint:gocritic // Narrow daemon access for best-effort summary cache writes. |
| 9801 | updateCtx := dbauthz.AsChatd(ctx) |
| 9802 | updateCtx, cancel := context.WithTimeout(updateCtx, turnStatusLabelWriteTimeout) |
| 9803 | defer cancel() |
| 9804 | |
| 9805 | affected, err := p.db.UpdateChatLastTurnSummary(updateCtx, database.UpdateChatLastTurnSummaryParams{ |
| 9806 | ID: chat.ID, |
| 9807 | ExpectedUpdatedAt: expectedUpdatedAt, |
| 9808 | LastTurnSummary: lastTurnSummary, |
| 9809 | }) |
| 9810 | if err != nil { |
| 9811 | logger.Warn(updateCtx, "failed to update chat turn summary", |
| 9812 | slog.F("chat_id", chat.ID), |
| 9813 | slog.Error(err), |
| 9814 | ) |
| 9815 | return |
| 9816 | } |
| 9817 | if affected == 0 { |
| 9818 | if summary != "" { |
| 9819 | logger.Info(updateCtx, "skipped stale chat turn summary update with non-empty summary", |
| 9820 | slog.F("chat_id", chat.ID), |
| 9821 | slog.F("summary_length", len(summary)), |
| 9822 | slog.F("expected_updated_at", expectedUpdatedAt), |
| 9823 | ) |
| 9824 | return |
| 9825 | } |
| 9826 | logger.Debug(updateCtx, "skipped stale chat turn summary update", |
| 9827 | slog.F("chat_id", chat.ID), |
| 9828 | slog.F("expected_updated_at", expectedUpdatedAt), |
| 9829 | ) |
| 9830 | return |
| 9831 | } |
| 9832 | |
| 9833 | updatedChat := chat |
| 9834 | updatedChat.LastTurnSummary = lastTurnSummary |
| 9835 | p.publishChatPubsubEvent(updatedChat, codersdk.ChatWatchEventKindSummaryChange, nil) |
| 9836 | |
| 9837 | // AcquireChats uses SKIP LOCKED; re-wake so a wake racing this |
| 9838 | // UPDATE's row lock does not strand a freshly-pending chat. |
| 9839 | p.signalWake() |
| 9840 | } |
| 9841 | |
| 9842 | func (p *Server) webpushConfigured() bool { |
| 9843 | return p.webpushDispatcher != nil && p.webpushDispatcher.PublicKey() != "" |