filesmanager

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2025 License: GPL-2.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CacheStats

type CacheStats struct {
	TotalTorrents   int
	TotalFiles      int
	CachedTorrents  int
	OldestCacheAge  *time.Duration
	NewestCacheAge  *time.Duration
	AverageCacheAge *time.Duration
}

CacheStats provides statistics about the file cache

type CachedFile

type CachedFile struct {
	ID              int
	InstanceID      int
	TorrentHash     string
	FileIndex       int
	Name            string
	Size            int64
	Progress        float64
	Priority        int
	IsSeed          *bool
	PieceRangeStart int64
	PieceRangeEnd   int64
	Availability    float64
	CachedAt        time.Time
}

CachedFile represents a cached torrent file

type Repository

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

Repository handles database operations for torrent file caching

func NewRepository

func NewRepository(db dbinterface.Querier) *Repository

NewRepository creates a new files repository

func (*Repository) DeleteFiles

func (r *Repository) DeleteFiles(ctx context.Context, instanceID int, hash string) error

DeleteFiles removes all cached files for a torrent. Returns nil if successful or if no cache existed for the given torrent. To distinguish between "deleted" vs "nothing to delete", check the logs or use GetFiles before calling this method.

func (*Repository) DeleteOldCache

func (r *Repository) DeleteOldCache(ctx context.Context, olderThan time.Time) (int, error)

DeleteOldCache removes cache entries older than the specified time

func (*Repository) DeleteSyncInfo

func (r *Repository) DeleteSyncInfo(ctx context.Context, instanceID int, hash string) (err error)

DeleteSyncInfo removes sync metadata for a torrent

func (*Repository) GetCacheStats

func (r *Repository) GetCacheStats(ctx context.Context, instanceID int) (*CacheStats, error)

GetCacheStats returns statistics about the cache for an instance

func (*Repository) GetFiles

func (r *Repository) GetFiles(ctx context.Context, instanceID int, hash string) ([]CachedFile, error)

GetFiles retrieves all cached files for a torrent

func (*Repository) GetFilesTx

func (r *Repository) GetFilesTx(ctx context.Context, tx dbinterface.TxQuerier, instanceID int, hash string) ([]CachedFile, error)

GetFilesTx retrieves all cached files for a torrent within a transaction

func (*Repository) GetSyncInfo

func (r *Repository) GetSyncInfo(ctx context.Context, instanceID int, hash string) (*SyncInfo, error)

GetSyncInfo retrieves sync metadata for a torrent

func (*Repository) GetSyncInfoTx

func (r *Repository) GetSyncInfoTx(ctx context.Context, tx dbinterface.TxQuerier, instanceID int, hash string) (*SyncInfo, error)

GetSyncInfoTx retrieves sync metadata for a torrent within a transaction

func (*Repository) UpsertFiles

func (r *Repository) UpsertFiles(ctx context.Context, files []CachedFile) error

UpsertFiles inserts or updates cached file information.

CONCURRENCY MODEL: This function uses eventual consistency with last-writer-wins semantics. If two goroutines cache the same torrent concurrently: - Each file row UPSERT is atomic at the SQLite level - The last write wins for each individual file - Progress/availability values may briefly be inconsistent across files - This is acceptable because:

  1. Cache freshness checks (5min TTL for active torrents) limit staleness
  2. Complete torrents (100% progress) have stable values
  3. UI shows slightly stale data briefly, then refreshes naturally
  4. Strict consistency would require distributed locks with significant overhead

Alternative approaches considered but rejected: - Optimistic locking with version numbers: adds complexity, breaks on every concurrent write - Exclusive locks during cache write: defeats purpose of caching, creates bottleneck

ATOMICITY: All files are upserted within a single transaction to ensure all-or-nothing semantics. If any file insert fails, the entire operation is rolled back to prevent partial cache states.

func (*Repository) UpsertSyncInfo

func (r *Repository) UpsertSyncInfo(ctx context.Context, info SyncInfo) error

UpsertSyncInfo inserts or updates sync metadata

type Service

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

Service manages cached torrent file information

func NewService

func NewService(db dbinterface.Querier) *Service

NewService creates a new files manager service

func (*Service) CacheFiles

func (s *Service) CacheFiles(ctx context.Context, instanceID int, hash string, torrentProgress float64, files qbt.TorrentFiles) error

CacheFiles stores file information in the database

func (*Service) CleanupStaleCache

func (s *Service) CleanupStaleCache(ctx context.Context, olderThan time.Duration) (int, error)

CleanupStaleCache removes old cache entries

func (*Service) GetCacheStats

func (s *Service) GetCacheStats(ctx context.Context, instanceID int) (*CacheStats, error)

GetCacheStats returns statistics about the cache

func (*Service) GetCachedFiles

func (s *Service) GetCachedFiles(ctx context.Context, instanceID int, hash string, torrentProgress float64) (qbt.TorrentFiles, error)

GetCachedFiles retrieves cached file information for a torrent. Returns nil if no cache exists or cache is stale.

CONCURRENCY NOTE: This function does NOT use transactions to avoid deadlocks. There's a small TOCTOU race where cache could be invalidated between sync check and file retrieval, but this is acceptable because: 1. The worst case is serving slightly stale data (same as normal cache behavior) 2. Cache invalidation is triggered by user actions (rename, delete, etc.) 3. The cache has built-in freshness checks that limit staleness (5 min for active torrents) 4. Complete torrents have stable file lists, so stale data is functionally equivalent 5. Avoiding transactions prevents deadlocks during concurrent operations (backups, writes, etc.)

If absolute consistency is required, the caller should invalidate the cache before calling this method, or use the qBittorrent API directly.

func (*Service) InvalidateCache

func (s *Service) InvalidateCache(ctx context.Context, instanceID int, hash string) error

InvalidateCache removes cached file information for a torrent

type SyncInfo

type SyncInfo struct {
	InstanceID      int
	TorrentHash     string
	LastSyncedAt    time.Time
	TorrentProgress float64
	FileCount       int
}

SyncInfo tracks when a torrent's files were last synced

Jump to

Keyboard shortcuts

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