MCPcopy Index your code
hub / github.com/coder/coder / ArchiveChat

Method ArchiveChat

coderd/x/chatd/chatd.go:2200–2277  ·  view source on GitHub ↗

ArchiveChat archives a chat family and broadcasts deleted events for each affected chat so watching clients converge without a full refetch. If the target chat is pending or running, it first transitions the chat back to waiting so active processing stops before the archive is broadcast.

(ctx context.Context, chat database.Chat)

Source from the content-addressed store, hash-verified

2198// target chat is pending or running, it first transitions the chat back to
2199// waiting so active processing stops before the archive is broadcast.
2200func (p *Server) ArchiveChat(ctx context.Context, chat database.Chat) error {
2201 if chat.ID == uuid.Nil {
2202 return xerrors.New("chat_id is required")
2203 }
2204
2205 var (
2206 archivedChats []database.Chat
2207 interruptedChats []database.Chat
2208 )
2209 if err := p.db.InTx(func(tx database.Store) error {
2210 if _, err := tx.GetChatByIDForUpdate(ctx, chat.ID); err != nil {
2211 return xerrors.Errorf("lock chat for archive: %w", err)
2212 }
2213
2214 var err error
2215 archivedChats, err = tx.ArchiveChatByID(ctx, chat.ID)
2216 if err != nil {
2217 return xerrors.Errorf("archive chat: %w", err)
2218 }
2219
2220 for i, archivedChat := range archivedChats {
2221 if archivedChat.Status != database.ChatStatusPending &&
2222 archivedChat.Status != database.ChatStatusRunning {
2223 continue
2224 }
2225
2226 updatedChat, updateErr := tx.UpdateChatStatus(ctx, database.UpdateChatStatusParams{
2227 ID: archivedChat.ID,
2228 Status: database.ChatStatusWaiting,
2229 WorkerID: uuid.NullUUID{},
2230 StartedAt: sql.NullTime{},
2231 HeartbeatAt: sql.NullTime{},
2232 LastError: pqtype.NullRawMessage{},
2233 })
2234 if updateErr != nil {
2235 return xerrors.Errorf("set archived chat waiting before cleanup: %w", updateErr)
2236 }
2237 archivedChats[i] = updatedChat
2238 interruptedChats = append(interruptedChats, updatedChat)
2239 }
2240 return nil
2241 }, nil); err != nil {
2242 return err
2243 }
2244
2245 for _, interruptedChat := range interruptedChats {
2246 p.publishStatus(interruptedChat.ID, interruptedChat.Status, interruptedChat.WorkerID)
2247 p.publishChatPubsubEvent(interruptedChat, codersdk.ChatWatchEventKindStatusChange, nil)
2248 }
2249
2250 // Archiving can race with an interrupted worker still flushing its
2251 // final debug writes. Retry a few times so orphaned rows are
2252 // removed quickly instead of waiting for the stale sweeper. Source
2253 // archiveCutoff from the DB-stamped updated_at returned by
2254 // ArchiveChatByID so the filter uses the same clock that stamps
2255 // replacement-turn debug rows; subtract debugCleanupClockSkew so
2256 // replica clock drift cannot let the retry delete a replacement's
2257 // debug rows if an unarchive races ahead (see the constant for the

Calls 12

publishStatusMethod · 0.95
scheduleDebugCleanupMethod · 0.95
DeleteByChatIDMethod · 0.80
NewMethod · 0.65
InTxMethod · 0.65
GetChatByIDForUpdateMethod · 0.65
ArchiveChatByIDMethod · 0.65
UpdateChatStatusMethod · 0.65
AddMethod · 0.65
ErrorfMethod · 0.45