Documentation
¶
Index ¶
- Constants
- Variables
- type ActiveStream
- type CacheDetail
- type CustomFolders
- type DFSDetail
- type Downloader
- type EntryCache
- type EntryCacheItem
- type FileInfo
- func (f *FileInfo) ActiveDebrid() string
- func (f *FileInfo) ByteRange() *[2]int64
- func (f *FileInfo) CanDelete() bool
- func (f *FileInfo) Content() []byte
- func (f *FileInfo) InfoHash() string
- func (f *FileInfo) IsDir() bool
- func (f *FileInfo) IsRemote() bool
- func (f *FileInfo) ModTime() time.Time
- func (f *FileInfo) Mode() os.FileMode
- func (f *FileInfo) Name() string
- func (f *FileInfo) Parent() string
- func (f *FileInfo) SetSys(v interface{})
- func (f *FileInfo) Size() int64
- func (f *FileInfo) Sys() interface{}
- type FileProbeResult
- type FileProbeStatus
- type FixResult
- type Fixer
- func (f *Fixer) FixTorrent(ctx context.Context, entry *storage.Entry, skipCurrent bool) (*FixResult, error)
- func (f *Fixer) IsFailedToReinsert(infohash, debrid string) bool
- func (f *Fixer) MoveTorrent(entry *storage.Entry, debridName string, reinsert bool) (bool, error)
- func (f *Fixer) ResetFailureState(infohash string)
- type FixerRequest
- type ImportRequest
- type ImportType
- type Job
- type JobQueue
- type JobType
- type Manager
- func (m *Manager) AddNewNZB(ctx context.Context, req *ImportRequest) (string, error)
- func (m *Manager) AddNewTorrent(ctx context.Context, importReq *ImportRequest) error
- func (m *Manager) AddOrUpdate(entry *storage.Entry, callback func(t *storage.Entry)) error
- func (m *Manager) Arr() *arr.Storage
- func (m *Manager) Clients() *xsync.Map[string, debrid.Client]
- func (m *Manager) CopyEntry(entry *FileInfo, destPath string, delete bool) error
- func (m *Manager) DeleteEntry(infohash string, removePlacements bool) error
- func (m *Manager) DeleteTorrents(infohashes []string, removeFromDebrid bool) error
- func (m *Manager) EntryExists(infohash string) (bool, error)
- func (m *Manager) FilterDebrid(filter func(debrid.Client) bool) []debrid.Client
- func (m *Manager) GetActiveStreams() []*ActiveStream
- func (m *Manager) GetActiveStreamsCount() int
- func (m *Manager) GetBrokenFiles(item *storage.EntryItem, filenames []string) []string
- func (m *Manager) GetCustomFolders() []string
- func (m *Manager) GetDebridSpeedTestResult(provider string) (debridTypes.SpeedTestResult, bool)
- func (m *Manager) GetDownloadByteRange(torrentName, filename string) (*[2]int64, error)
- func (m *Manager) GetDownloadLink(ctx context.Context, entry *storage.Entry, filename string) (types.DownloadLink, error)
- func (m *Manager) GetEntries() []FileInfo
- func (m *Manager) GetEntry(infohash string) (*storage.Entry, error)
- func (m *Manager) GetEntryByName(torrentName, filename string) (*storage.Entry, error)
- func (m *Manager) GetEntryChildren(group string) (*FileInfo, []FileInfo)
- func (m *Manager) GetEntryInfo(name string) (*FileInfo, error)
- func (m *Manager) GetEntryItem(torrentName string) (*storage.EntryItem, error)
- func (m *Manager) GetIngests() ([]types.IngestData, error)
- func (m *Manager) GetIngestsByDebrid(debridName string) ([]types.IngestData, error)
- func (m *Manager) GetMigrationJob(jobID string) (*storage.SwitcherJob, error)
- func (m *Manager) GetStats() (map[string]interface{}, error)
- func (m *Manager) GetTorrentChildren(name string) (*FileInfo, []FileInfo)
- func (m *Manager) GetTorrentEntry(torrentName string) (*FileInfo, error)
- func (m *Manager) GetTorrentFile(torrentName, fileName string) (*FileInfo, error)
- func (m *Manager) GetTorrentMountPath(torrent *storage.Entry) string
- func (m *Manager) GetTorrents(filter func(*storage.Entry) bool) ([]*storage.Entry, error)
- func (m *Manager) GetTorrentsCount() (int, error)
- func (m *Manager) GetTotalActiveDownloadLinks() int
- func (m *Manager) HasUsenet() bool
- func (m *Manager) IsReady() chan struct{}
- func (m *Manager) Migrator() *Migrator
- func (m *Manager) MountManager() MountManager
- func (m *Manager) ProbeEntryFiles(ctx context.Context, item *storage.EntryItem, filenames []string, ...) []FileProbeResult
- func (m *Manager) ProviderClient(name string) debrid.Client
- func (m *Manager) Queue() *Queue
- func (m *Manager) RefreshEntries(refreshMount bool)
- func (m *Manager) RefreshMount() error
- func (m *Manager) ReinsertEntry(ctx context.Context, entry *storage.Entry) error
- func (m *Manager) RemoveEntry(entry *FileInfo) error
- func (m *Manager) RemoveFromProvider(providerEntry *storage.ProviderEntry) error
- func (m *Manager) RemoveTorrentFile(torrentName, filename string) error
- func (m *Manager) RemoveTorrentPlacements(t *storage.Entry)
- func (m *Manager) Repair() RepairManager
- func (m *Manager) Reset() error
- func (m *Manager) RootInfo() *FileInfo
- func (m *Manager) RunFFprobe(filePaths []string) error
- func (m *Manager) Scheduler() gocron.Scheduler
- func (m *Manager) SendToDebrid(ctx context.Context, importRequest *ImportRequest) (*debridTypes.Torrent, error)
- func (m *Manager) SetMountManager(mountMgr MountManager)
- func (m *Manager) SetRepairManager(repairMgr RepairManager)
- func (m *Manager) SpeedTest(ctx context.Context, req SpeedTestRequest) SpeedTestResponse
- func (m *Manager) Start(ctx context.Context) error
- func (m *Manager) StartTime() time.Time
- func (m *Manager) StartWorker(ctx context.Context) error
- func (m *Manager) Stop() error
- func (m *Manager) Storage() *storage.Storage
- func (m *Manager) Stream(ctx context.Context, entry *storage.Entry, filename string, start, end int64, ...) error
- func (m *Manager) SwitchTorrent(ctx context.Context, infohash, target string, keepOld, waitComplete bool) (*storage.SwitcherJob, error)
- func (m *Manager) TrackStream(entry *storage.Entry, filename, client string) string
- func (m *Manager) UntrackStream(streamID string)
- func (m *Manager) Uptime() time.Duration
- func (m *Manager) Usenet() *usenet.Usenet
- func (m *Manager) UsenetStats() map[string]interface{}
- type Migrator
- type MountManager
- type MountStats
- type Queue
- func (q *Queue) Add(torrent *storage.Entry) error
- func (q *Queue) Close()
- func (q *Queue) Delete(infohash string, cleanup func(t *storage.Entry) error) error
- func (q *Queue) DeleteRequest(requestID string) bool
- func (q *Queue) DeleteRequestWhere(predicate func(*ImportRequest) bool) int
- func (q *Queue) DeleteStalled(cleanup func(*storage.Entry) error) error
- func (q *Queue) DeleteWhere(category string, protocol config.Protocol, state storage.TorrentState, ...) error
- func (q *Queue) FindRequest(requestID string) *ImportRequest
- func (q *Queue) GetTorrent(infohash string) (*storage.Entry, error)
- func (q *Queue) IsEmpty() bool
- func (q *Queue) ListFilter(category string, protocol config.Protocol, state storage.TorrentState, ...) []*storage.Entry
- func (q *Queue) ListFilterFunc(category string, protocol config.Protocol, state storage.TorrentState, ...) func(*storage.Entry) bool
- func (q *Queue) PopRequest() (*ImportRequest, error)
- func (q *Queue) PushRequest(req *ImportRequest) error
- func (q *Queue) ReQueue(importReq *ImportRequest) error
- func (q *Queue) RequestsSize() int
- func (q *Queue) Update(torrent *storage.Entry) error
- func (q *Queue) UpdateWhere(predicate func(*storage.Entry) bool, updateFunc func(*storage.Entry) bool) error
- type RcloneDetail
- type RcloneMountInfo
- type RepairJobCounts
- type RepairJobOptions
- type RepairManager
- type SeasonInfo
- type SpeedTestRequest
- type SpeedTestResponse
- type StreamError
- type StreamMetadata
- type StreamReadyFunc
- type VFSDetail
Constants ¶
const ( EntryAllFolder string = "__all__" EntryBadFolder string = "__bad__" EntryTorrentFolder string = "torrents" EntryNZBFolder string = "nzbs" )
const ( MaxFFprobeWorkers = 10 MaxNZBPreCacheFiles = 5 FFprobeTimeout = 60 * time.Second )
Variables ¶
var (
ErrUnsupportedDebridProvider = errors.New("unsupported debrid provider")
)
Functions ¶
This section is empty.
Types ¶
type ActiveStream ¶
type ActiveStream struct {
ID string `json:"id"`
EntryName string `json:"entry_name"`
FileName string `json:"file_name"`
FileSize int64 `json:"file_size"`
Source string `json:"source"` // "torrent" or "nzb"
StartedAt int64 `json:"started_at"`
LastActive int64 `json:"last_active"` // Last activity timestamp (for observability)
Debrid string `json:"debrid,omitempty"`
Client string `json:"client,omitempty"` // Client identifier (User-Agent for WebDAV, "DFS" for DFS)
}
ActiveStream represents a currently active streaming file
type CacheDetail ¶
type CacheDetail struct {
TotalSize int64 `json:"total_size"`
MaxSize int64 `json:"max_size"`
ItemCount int64 `json:"item_count"`
Utilization float64 `json:"utilization"`
}
CacheDetail holds VFS cache statistics.
type CustomFolders ¶
type CustomFolders struct {
// contains filtered or unexported fields
}
type DFSDetail ¶
type DFSDetail struct {
Backend string `json:"backend"`
Ready bool `json:"ready"`
MountPath string `json:"mount_path"`
VFS VFSDetail `json:"vfs"`
}
DFSDetail holds DFS-specific mount statistics.
type Downloader ¶
type Downloader struct {
// contains filtered or unexported fields
}
func NewDownloadManager ¶
func NewDownloadManager(manager *Manager) *Downloader
NewDownloadManager creates a new strm manager
type EntryCache ¶
type EntryCache struct {
// contains filtered or unexported fields
}
func NewEntryCache ¶
func NewEntryCache(manager *Manager) *EntryCache
func (*EntryCache) Refresh ¶
func (e *EntryCache) Refresh()
Refresh triggers a cache refresh with debouncing. If called multiple times rapidly, only one refresh will occur.
type EntryCacheItem ¶
type EntryCacheItem struct {
// contains filtered or unexported fields
}
type FileInfo ¶
type FileInfo struct {
// contains filtered or unexported fields
}
FileInfo implements os.FileInfo
func (*FileInfo) ActiveDebrid ¶
type FileProbeResult ¶
type FileProbeStatus ¶
type FileProbeStatus string
const ( FileProbeHealthy FileProbeStatus = "healthy" FileProbeBroken FileProbeStatus = "broken" FileProbeUnknown FileProbeStatus = "unknown" )
type Fixer ¶
type Fixer struct {
// contains filtered or unexported fields
}
Fixer handles torrent repair with cascading re-insertion across debrids
func (*Fixer) FixTorrent ¶
func (f *Fixer) FixTorrent(ctx context.Context, entry *storage.Entry, skipCurrent bool) (*FixResult, error)
FixTorrent attempts to fix a broken torrent by re-inserting across debrids Strategy: 1. Try to re-insert on current active debrid, except if skipCurrent is true 2. If fails, cascade through other debrids in config order 3. Skip debrids where torrent already exists (unless they're also broken) 4. Mark as completely failed if all debrids fail
func (*Fixer) IsFailedToReinsert ¶
IsFailedToReinsert checks if a torrent has been marked as failed to re-insert
func (*Fixer) MoveTorrent ¶
MoveTorrent attempts to re-insert a torrent on a specific debrid
func (*Fixer) ResetFailureState ¶
ResetFailureState manually resets the failure state for a torrent
type FixerRequest ¶
type FixerRequest struct {
InfoHash string
CurrentDebrid string
AttemptedDebrids []string
StartedAt time.Time
LastAttempt time.Time
// contains filtered or unexported fields
}
FixerRequest tracks an ongoing repair operation
type ImportRequest ¶
type ImportRequest struct {
Name string `json:"name"`
NZBContent []byte `json:"-,omitempty"`
Id string `json:"id"`
DownloadFolder string `json:"downloadFolder"`
SelectedDebrid string `json:"debrid"`
Magnet *utils.Magnet `json:"magnet"`
Arr *arr.Arr `json:"arr"`
Action config.DownloadAction `json:"action"`
DownloadUncached *bool `json:"downloadUncached"`
CallBackUrl string `json:"callBackUrl"`
SkipMultiSeason bool `json:"skip_multi_season"`
Status string `json:"status"`
CompletedAt time.Time `json:"completedAt,omitempty"`
Error string `json:"error,omitempty"`
Type ImportType `json:"type"`
Async bool `json:"async"`
}
func NewNZBRequest ¶
func NewNZBRequest(name, downloadFolder string, nzbContent []byte, arr *arr.Arr, action config.DownloadAction, callBackUrl string, importType ImportType, skipMultiSeason bool) *ImportRequest
func NewTorrentRequest ¶
func NewTorrentRequest(debrid string, downloadFolder string, magnet *utils.Magnet, arr *arr.Arr, action config.DownloadAction, downloadUncached *bool, callBackUrl string, importType ImportType, skipMultiSeason bool) *ImportRequest
type ImportType ¶
type ImportType string
const ( ImportTypeQBit ImportType = "qbit" ImportTypeAPI ImportType = "api" ImportTypeSABnzbd ImportType = "sabnzbd" ImportSwitcher ImportType = "switcher" )
type Job ¶
type Job struct {
ID string
Type JobType
Request *ImportRequest // The original import request
NZBMeta *storage.NZB // NZB metadata (set after parse, before worker processes)
NZBGroups map[string]*parser.FileGroup // NZB file groups (set after parse)
Entry *storage.Entry // Entry created during processing
CreatedAt time.Time
}
Job represents a unified processing job for both torrents and NZBs
type JobQueue ¶
type JobQueue struct {
// contains filtered or unexported fields
}
JobQueue is a unified, unbounded, thread-safe job queue with a fixed worker pool. It replaces the separate ImportRequest queue, nzbJobQueue, and unbounded goroutine fan-out with a single queue that processes both torrent and NZB jobs.
func NewJobQueue ¶
func NewJobQueue(ctx context.Context, maxWorkers int, processFunc func(ctx context.Context, job *Job)) *JobQueue
NewJobQueue creates a new unified job queue with the given number of workers
func (*JobQueue) Close ¶
func (q *JobQueue) Close()
Close signals all workers to stop and waits for them to finish
func (*JobQueue) DeleteJob ¶
DeleteJob removes a pending job by ID (before it's picked up by a worker). Returns true if the job was found and removed.
func (*JobQueue) PendingCount ¶
PendingCount returns the count of pending jobs, optionally filtered by type
type Manager ¶
type Manager struct {
// Notifications service
Notifications *notifications.Service
// contains filtered or unexported fields
}
Manager handles unified torrent management - replaces wire.Store completely
func (*Manager) AddNewTorrent ¶
func (m *Manager) AddNewTorrent(ctx context.Context, importReq *ImportRequest) error
AddNewTorrent creates a torrent from import request and processes it
func (*Manager) AddOrUpdate ¶
func (*Manager) DeleteEntry ¶
DeleteEntry deletes a torrent by infohash
func (*Manager) DeleteTorrents ¶
func (*Manager) FilterDebrid ¶
FilterDebrid returns clients that match the filter function
func (*Manager) GetActiveStreams ¶
func (m *Manager) GetActiveStreams() []*ActiveStream
GetActiveStreams returns all currently active streams.
func (*Manager) GetActiveStreamsCount ¶
GetActiveStreamsCount returns the number of active streams.
func (*Manager) GetBrokenFiles ¶
func (*Manager) GetCustomFolders ¶
func (*Manager) GetDebridSpeedTestResult ¶
func (m *Manager) GetDebridSpeedTestResult(provider string) (debridTypes.SpeedTestResult, bool)
GetDebridSpeedTestResult returns stored speed test result for a specific debrid provider
func (*Manager) GetDownloadByteRange ¶
GetDownloadByteRange gets the byte range for a file
func (*Manager) GetDownloadLink ¶
func (m *Manager) GetDownloadLink(ctx context.Context, entry *storage.Entry, filename string) (types.DownloadLink, error)
GetDownloadLink fetches and validates a download link for a file in an entry. This is the public interface that delegates to the link service.
func (*Manager) GetEntries ¶
GetEntries returns the subdirectories under a given mount name it would show __all__, __bad__, torrents, nzbs, per-provider folders and any custom folders
func (*Manager) GetEntryByName ¶
func (*Manager) GetEntryChildren ¶
func (*Manager) GetEntryInfo ¶
GetEntryInfo returns a FileInfo for a torrent/entry by name - O(1) lookup
func (*Manager) GetEntryItem ¶
func (*Manager) GetIngests ¶
func (m *Manager) GetIngests() ([]types.IngestData, error)
func (*Manager) GetIngestsByDebrid ¶
func (m *Manager) GetIngestsByDebrid(debridName string) ([]types.IngestData, error)
func (*Manager) GetMigrationJob ¶
func (m *Manager) GetMigrationJob(jobID string) (*storage.SwitcherJob, error)
func (*Manager) GetTorrentChildren ¶
func (*Manager) GetTorrentEntry ¶
func (*Manager) GetTorrentFile ¶
func (*Manager) GetTorrentMountPath ¶
GetTorrentMountPath returns the full mount path for a torrent Returns the path based on the new unified mount structure
func (*Manager) GetTorrents ¶
func (*Manager) GetTorrentsCount ¶
func (*Manager) GetTotalActiveDownloadLinks ¶
GetTotalActiveDownloadLinks returns the total number of active download links across all debrids
func (*Manager) MountManager ¶
func (m *Manager) MountManager() MountManager
func (*Manager) ProbeEntryFiles ¶
func (m *Manager) ProbeEntryFiles(ctx context.Context, item *storage.EntryItem, filenames []string, strategy ...storage.RepairStrategy) []FileProbeResult
func (*Manager) RefreshEntries ¶
func (*Manager) RefreshMount ¶
func (*Manager) ReinsertEntry ¶
func (*Manager) RemoveEntry ¶
func (*Manager) RemoveFromProvider ¶
func (m *Manager) RemoveFromProvider(providerEntry *storage.ProviderEntry) error
func (*Manager) RemoveTorrentFile ¶
func (*Manager) RemoveTorrentPlacements ¶
func (*Manager) Repair ¶
func (m *Manager) Repair() RepairManager
func (*Manager) Reset ¶
Reset resets the manager with the new configuration This is called after config changes (e.g., setup wizard) to apply new settings
func (*Manager) RunFFprobe ¶
RunFFprobe runs ffprobe on the given file paths to warm up caches and trigger imports. Uses: ffprobe -v quiet -print_format json -show_format -show_streams <file>
func (*Manager) SendToDebrid ¶
func (m *Manager) SendToDebrid(ctx context.Context, importRequest *ImportRequest) (*debridTypes.Torrent, error)
SendToDebrid submits a magnet to debrid service(s) - replaces debrid.Parse
func (*Manager) SetMountManager ¶
func (m *Manager) SetMountManager(mountMgr MountManager)
func (*Manager) SetRepairManager ¶
func (m *Manager) SetRepairManager(repairMgr RepairManager)
func (*Manager) SpeedTest ¶
func (m *Manager) SpeedTest(ctx context.Context, req SpeedTestRequest) SpeedTestResponse
SpeedTest runs a speed test for a specific provider based on protocol
func (*Manager) Stream ¶
func (m *Manager) Stream(ctx context.Context, entry *storage.Entry, filename string, start, end int64, writer io.Writer, onReady StreamReadyFunc, client string) error
Stream streams a file from an entry to the provided writer within the specified byte range. client identifies the caller (e.g., User-Agent for WebDAV, "DFS" for DFS mount).
func (*Manager) SwitchTorrent ¶
func (m *Manager) SwitchTorrent(ctx context.Context, infohash, target string, keepOld, waitComplete bool) (*storage.SwitcherJob, error)
SwitchTorrent moves a torrent from one debrid to another
func (*Manager) TrackStream ¶
TrackStream registers an active stream for observability and returns the stream ID. Call UntrackStream with the returned ID when streaming completes.
func (*Manager) UntrackStream ¶
UntrackStream removes a previously-registered active stream if the ID is non-empty.
func (*Manager) UsenetStats ¶
UsenetStats returns usenet client statistics
type Migrator ¶
type Migrator struct {
// contains filtered or unexported fields
}
Migrator handles migration from cache JSON files to unified bbolt system
func NewMigrator ¶
NewMigrator creates a new migrator
func (*Migrator) GetStatus ¶
func (m *Migrator) GetStatus() (*storage.SystemMigrationStatus, error)
GetStatus returns the current migration status
type MountManager ¶
type MountManager interface {
Start(ctx context.Context) error
Stop() error
Stats() map[string]interface{}
IsReady() bool
Type() string
Refresh(dirs []string) error
}
func NewStubMountManager ¶
func NewStubMountManager() MountManager
type MountStats ¶
type MountStats struct {
Enabled bool `json:"enabled"`
Ready bool `json:"ready"`
Type string `json:"type,omitempty"`
Error string `json:"error,omitempty"`
DFS *DFSDetail `json:"dfs,omitempty"`
Rclone *RcloneDetail `json:"rclone,omitempty"`
External *RcloneDetail `json:"external,omitempty"`
}
MountStats is the unified stats struct returned by all MountManager implementations. Each mount type populates only its relevant field.
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
func (*Queue) DeleteRequest ¶
DeleteRequest specific request by ID
func (*Queue) DeleteRequestWhere ¶
func (q *Queue) DeleteRequestWhere(predicate func(*ImportRequest) bool) int
DeleteRequestWhere requests matching a condition
func (*Queue) DeleteStalled ¶
func (*Queue) DeleteWhere ¶
func (*Queue) FindRequest ¶
func (q *Queue) FindRequest(requestID string) *ImportRequest
FindRequest request without removing it
func (*Queue) ListFilter ¶
func (*Queue) ListFilterFunc ¶
func (*Queue) PopRequest ¶
func (q *Queue) PopRequest() (*ImportRequest, error)
func (*Queue) PushRequest ¶
func (q *Queue) PushRequest(req *ImportRequest) error
func (*Queue) ReQueue ¶
func (q *Queue) ReQueue(importReq *ImportRequest) error
func (*Queue) RequestsSize ¶
type RcloneDetail ¶
type RcloneDetail struct {
Core rclone.CoreStatsResponse `json:"core"`
Memory rclone.MemoryStats `json:"memory"`
Bandwidth rclone.BandwidthStats `json:"bandwidth"`
Version rclone.VersionResponse `json:"version"`
Mount *RcloneMountInfo `json:"mount,omitempty"`
}
RcloneDetail holds rclone/external-specific mount statistics.
type RcloneMountInfo ¶
type RcloneMountInfo struct {
LocalPath string `json:"local_path"`
WebDAVURL string `json:"webdav_url"`
Mounted bool `json:"mounted"`
MountedAt string `json:"mounted_at,omitempty"`
ConfigName string `json:"config_name"`
Error string `json:"error,omitempty"`
}
RcloneMountInfo holds rclone mount point information.
type RepairJobCounts ¶
type RepairJobCounts struct {
Active int `json:"active_jobs"`
Pending int `json:"pending_jobs"`
Completed int `json:"completed_jobs"`
Failed int `json:"failed_jobs"`
}
RepairJobCounts holds per-status counts of repair jobs.
type RepairJobOptions ¶
type RepairManager ¶
type SeasonInfo ¶
SeasonInfo represents information about a season in a multi-season torrent
type SpeedTestRequest ¶
type SpeedTestRequest struct {
Protocol string `json:"protocol"` // "nntp" or "debrid"
Provider string `json:"provider"` // provider host/identifier
}
SpeedTestRequest represents a speed test request payload
type SpeedTestResponse ¶
type SpeedTestResponse struct {
Provider string `json:"provider"`
Protocol string `json:"protocol"`
SpeedMBps float64 `json:"speed_mbps"`
LatencyMs int64 `json:"latency_ms"`
BytesRead int64 `json:"bytes_read"`
TestedAt string `json:"tested_at"`
Error string `json:"error,omitempty"`
}
SpeedTestResponse represents a speed test result
type StreamError ¶
type StreamError struct {
Err error
Retryable bool
LinkError bool // true if we should try a new link
}
func (StreamError) Error ¶
func (e StreamError) Error() string
type StreamMetadata ¶
StreamMetadata describes the headers/status for a streaming response before data flows.
type StreamReadyFunc ¶
type StreamReadyFunc func(*StreamMetadata) error
StreamReadyFunc allows callers to copy headers/status before streaming begins.