archive

package
v0.2.49 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: GPL-2.0, GPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package archive implements the chat archive lifecycle: move to archive, list, restore, update summary, delete, and age-based purge. Separated from the core chat store to give the archive subsystem its own package boundary and make the purge scheduler independently testable.

Index

Constants

View Source
const Subdir = "archive"

Subdir is the subdirectory name under the chats directory where archived chats are stored. Exported so composition-layer code can reference it without hardcoding the literal.

Variables

This section is empty.

Functions

func OldestArchiveMTime

func OldestArchiveMTime(ctx context.Context, storeDir string) (time.Time, bool)

OldestArchiveMTime returns the mtime of the oldest file in the archive directory and true, or the zero time and false if the directory is empty or unreadable.

Types

type IDInUseError

type IDInUseError struct {
	ID string
}

IDInUseError indicates the target chat ID is already used by an active (non-archived) chat.

func (*IDInUseError) Error

func (e *IDInUseError) Error() string

type Option

type Option func(*Service)

Option configures the archive Service.

func WithOnArchive

func WithOnArchive(fn func(chatID api.ChatID)) Option

WithOnArchive registers a callback fired after a chat is archived.

func WithOnPurge

func WithOnPurge(fn func(chatID api.ChatID)) Option

WithOnPurge registers a callback fired after an archived chat is purged.

func WithPreArchive added in v0.1.165

func WithPreArchive(fn func(chatID api.ChatID)) Option

WithPreArchive registers a callback fired BEFORE a chat's file is moved to the archive dir. Used to run the hub's in-memory teardown (close the bridge, kill terminals, clear pending state, remove the .partial) while the chat record is still active, so archiving can't orphan a live bridge or leave a ghost .partial.

type PurgeScheduler

type PurgeScheduler struct {
	// contains filtered or unexported fields
}

PurgeScheduler owns the archive-purge lifecycle. Uses a dedicated goroutine with a trigger channel for true collapse semantics.

func NewPurgeScheduler

func NewPurgeScheduler(ctx context.Context, svc *Service, retention func() time.Duration) *PurgeScheduler

NewPurgeScheduler builds a scheduler that runs purges based on the retention value returned by `retention`.

func (*PurgeScheduler) Done

func (p *PurgeScheduler) Done() <-chan struct{}

Done returns a channel that is closed when the scheduler goroutine exits.

func (*PurgeScheduler) Start

func (p *PurgeScheduler) Start()

Start launches the scheduler goroutine and runs an initial evaluation.

func (*PurgeScheduler) Stop

func (p *PurgeScheduler) Stop()

Stop signals the scheduler goroutine to exit and waits for it to finish.

func (*PurgeScheduler) Trigger

func (p *PurgeScheduler) Trigger()

Trigger requests a purge evaluation. Safe to call from any goroutine; concurrent calls collapse into a single pending evaluation.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service implements the archive lifecycle operations.

func New

func New(store StoreAccess, opts ...Option) *Service

New creates an archive Service backed by the given StoreAccess.

func (*Service) Archive

func (s *Service) Archive(ctx context.Context, chatID api.ChatID) error

Archive moves a chat from the active directory to the archive subdirectory. Takes the per-chat mutex so a concurrent Mutate / AppendMessage can't race the rename. Broadcasts chat_deleted so all connected clients see the entry disappear without a manual refresh.

func (*Service) DeleteArchived

func (s *Service) DeleteArchived(ctx context.Context, chatID api.ChatID) error

DeleteArchived permanently removes a single archived chat file and its plan draft. Fires onPurge so checkpoint data is cleaned up.

func (*Service) ListArchived

func (s *Service) ListArchived(ctx context.Context) []api.ChatHeader

ListArchived returns headers for all archived chats, sorted by UpdatedAt desc. Files that fail to read or parse are logged and skipped. Always returns a non-nil slice.

func (*Service) LoadArchived

func (s *Service) LoadArchived(ctx context.Context, chatID api.ChatID) (*api.Chat, error)

LoadArchived reads the archived chat and returns the parsed *api.Chat.

func (*Service) Purge

func (s *Service) Purge(ctx context.Context, maxAge time.Duration)

Purge deletes archived chats older than maxAge.

func (*Service) RestoreArchived

func (s *Service) RestoreArchived(ctx context.Context, chatID api.ChatID) error

RestoreArchived moves a chat from the archive back to the active directory. Refuses with error if an active chat already exists at the target id.

func (*Service) UpdateArchivedSummary

func (s *Service) UpdateArchivedSummary(ctx context.Context, chatID api.ChatID, summary string) error

UpdateArchivedSummary rewrites an archived chat's Summary field in place. Used by the hub to populate the one-line summary produced by the utility bridge after archiving.

type StoreAccess

type StoreAccess interface {
	// Lock returns the per-chat mutex for serialization.
	Lock(chatID api.ChatID) *sync.Mutex
	// Dir returns the store's base directory.
	Dir() string
	// PathFor returns the path to the active chat file.
	PathFor(chatID api.ChatID) (string, error)
	// Load reads a chat from the active directory.
	Load(chatID api.ChatID) (*api.Chat, error)
	// Header builds a ChatHeader from a Chat.
	Header(ctx context.Context, c *api.Chat) api.ChatHeader
	// MarkDeleted records a tombstone for the chat ID.
	MarkDeleted(chatID api.ChatID)
	// ClearTombstone removes the tombstone for a restored chat.
	ClearTombstone(chatID api.ChatID)
	// Broadcast returns the broadcaster (may be nil).
	Broadcast() api.Broadcaster
	// OldestCheckpoint returns the checkpoint lookup function (may be nil).
	OldestCheckpoint() func(ctx context.Context, chatID api.ChatID) string
}

StoreAccess is the narrow interface the archive subsystem requires from the chat store. Keeps the dependency minimal and testable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL