Documentation
¶
Index ¶
- type CacheStats
- type CachedFile
- type InstanceLister
- type Repository
- func (r *Repository) DeleteCacheForRemovedTorrents(ctx context.Context, instanceID int, currentHashes []string) (int, error)
- func (r *Repository) DeleteFiles(ctx context.Context, instanceID int, hash string) error
- func (r *Repository) DeleteTorrentCache(ctx context.Context, instanceID int, hashes []string) error
- func (r *Repository) GetCacheStats(ctx context.Context, instanceID int) (*CacheStats, error)
- func (r *Repository) GetFiles(ctx context.Context, instanceID int, hash string) ([]CachedFile, error)
- func (r *Repository) GetFilesBatch(ctx context.Context, instanceID int, hashes []string) (map[string][]CachedFile, error)
- func (r *Repository) GetFilesTx(ctx context.Context, tx dbinterface.TxQuerier, instanceID int, hash string) ([]CachedFile, error)
- func (r *Repository) GetSyncInfo(ctx context.Context, instanceID int, hash string) (*SyncInfo, error)
- func (r *Repository) GetSyncInfoBatch(ctx context.Context, instanceID int, hashes []string) (map[string]*SyncInfo, error)
- func (r *Repository) GetSyncInfoTx(ctx context.Context, tx dbinterface.TxQuerier, instanceID int, hash string) (*SyncInfo, error)
- func (r *Repository) UpsertFiles(ctx context.Context, files []CachedFile) error
- func (r *Repository) UpsertSyncInfo(ctx context.Context, info SyncInfo) error
- func (r *Repository) UpsertSyncInfoBatch(ctx context.Context, infos []SyncInfo) error
- type Service
- func (s *Service) CacheFiles(ctx context.Context, instanceID int, hash string, files qbt.TorrentFiles) error
- func (s *Service) CacheFilesBatch(ctx context.Context, instanceID int, files map[string]qbt.TorrentFiles) error
- func (s *Service) CleanupRemovedTorrentsCache(ctx context.Context, instanceID int, currentHashes []string) (int, error)
- func (s *Service) GetCacheStats(ctx context.Context, instanceID int) (*CacheStats, error)
- func (s *Service) GetCachedFiles(ctx context.Context, instanceID int, hash string) (qbt.TorrentFiles, error)
- func (s *Service) GetCachedFilesBatch(ctx context.Context, instanceID int, hashes []string) (map[string]qbt.TorrentFiles, []string, error)
- func (s *Service) InvalidateCache(ctx context.Context, instanceID int, hash string) error
- func (s *Service) StartOrphanCleanup(ctx context.Context, instances InstanceLister, hashes TorrentHashProvider)
- type SyncInfo
- type TorrentHashProvider
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 InstanceLister ¶ added in v1.12.0
InstanceLister lists all qBittorrent instances
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) DeleteCacheForRemovedTorrents ¶ added in v1.8.0
func (r *Repository) DeleteCacheForRemovedTorrents(ctx context.Context, instanceID int, currentHashes []string) (int, error)
DeleteCacheForRemovedTorrents removes cache entries for torrents that no longer exist
func (*Repository) DeleteFiles ¶
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) DeleteTorrentCache ¶ added in v1.8.0
DeleteTorrentCache removes all cache data for multiple torrents (both files and sync info)
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) GetFilesBatch ¶ added in v1.8.0
func (r *Repository) GetFilesBatch(ctx context.Context, instanceID int, hashes []string) (map[string][]CachedFile, error)
GetFilesBatch retrieves cached files for multiple torrents at once.
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) GetSyncInfoBatch ¶ added in v1.8.0
func (r *Repository) GetSyncInfoBatch(ctx context.Context, instanceID int, hashes []string) (map[string]*SyncInfo, error)
GetSyncInfoBatch retrieves sync metadata for multiple torrents in a single query.
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:
- Cache freshness checks (5min TTL for active torrents) limit staleness
- Complete torrents (100% progress) have stable values
- UI shows slightly stale data briefly, then refreshes naturally
- 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
func (*Repository) UpsertSyncInfoBatch ¶ added in v1.8.0
func (r *Repository) UpsertSyncInfoBatch(ctx context.Context, infos []SyncInfo) error
UpsertSyncInfoBatch inserts or updates sync metadata for multiple torrents
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, files qbt.TorrentFiles) error
CacheFiles stores file information in the database
func (*Service) CacheFilesBatch ¶ added in v1.8.0
func (s *Service) CacheFilesBatch(ctx context.Context, instanceID int, files map[string]qbt.TorrentFiles) error
CacheFilesBatch stores file information for multiple torrents in the database
func (*Service) CleanupRemovedTorrentsCache ¶ added in v1.8.0
func (s *Service) CleanupRemovedTorrentsCache(ctx context.Context, instanceID int, currentHashes []string) (int, error)
CleanupRemovedTorrentsCache removes cache entries for torrents that no longer exist
func (*Service) GetCacheStats ¶
GetCacheStats returns statistics about the cache
func (*Service) GetCachedFiles ¶
func (s *Service) GetCachedFiles(ctx context.Context, instanceID int, hash string) (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, 30 min for completed) 4. 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) GetCachedFilesBatch ¶ added in v1.8.0
func (s *Service) GetCachedFilesBatch(ctx context.Context, instanceID int, hashes []string) (map[string]qbt.TorrentFiles, []string, error)
GetCachedFilesBatch retrieves cached file information for multiple torrents. Missing or stale entries are returned in the second slice so callers can decide what to refresh.
func (*Service) InvalidateCache ¶
InvalidateCache removes cached file information for a torrent
func (*Service) StartOrphanCleanup ¶ added in v1.12.0
func (s *Service) StartOrphanCleanup(ctx context.Context, instances InstanceLister, hashes TorrentHashProvider)
StartOrphanCleanup starts a background goroutine that periodically removes orphaned cache entries (entries for torrents that no longer exist in qBittorrent). Runs cleanup on startup and then hourly.