Documentation
¶
Index ¶
- Constants
- func ComputeTier(state *models.SiteLoginState, effective, now time.Time) string
- func DaysRemaining(state *models.SiteLoginState, effective, now time.Time) int
- func EffectiveLastActive(state *models.SiteLoginState, now time.Time) time.Time
- type CleanupMonitor
- type CredentialDecryptor
- type CronExpr
- type FreeEndMonitor
- type JobStatus
- type LoginReminderConfig
- type LoginReminderMonitor
- func (m *LoginReminderMonitor) RunProbeOnce(ctx context.Context)
- func (m *LoginReminderMonitor) RunProbeOnceForSite(ctx context.Context, siteName string) bool
- func (m *LoginReminderMonitor) RunProbeOnceForSiteLocked(ctx context.Context, siteName string)
- func (m *LoginReminderMonitor) RunReminderOnce(ctx context.Context)
- func (m *LoginReminderMonitor) SendTestReminder(ctx context.Context, siteName string) error
- func (m *LoginReminderMonitor) Start()
- func (m *LoginReminderMonitor) Stop()
- func (m *LoginReminderMonitor) TryAcquireProbeLock(siteName string) (release func(), ok bool)
- type Manager
- func (m *Manager) GetDownloaderManager() *downloader.DownloaderManager
- func (m *Manager) GetFreeEndMonitor() *FreeEndMonitor
- func (m *Manager) GetLoginReminderMonitor() *LoginReminderMonitor
- func (m *Manager) InitFreeEndMonitor()
- func (m *Manager) LastVersion() int64
- func (m *Manager) ListJobs() []JobStatus
- func (m *Manager) Reload(cfg *models.Config)
- func (m *Manager) SetLoginReminderMonitor(mon *LoginReminderMonitor)
- func (m *Manager) Start(site models.SiteGroup, r models.RSSConfig, runner func(ctx context.Context))
- func (m *Manager) StartAll(cfg *models.Config)
- func (m *Manager) Stop(site models.SiteGroup, rssName string)
- func (m *Manager) StopAll()
- type PeerRatioMonitor
- type QuietHours
- type SiteResolver
Constants ¶
const ( ProbeModeAuto = "auto" ProbeModeManual = "manual" ProbeModeDisabled = "disabled" )
const (
PauseReasonPeerRatio = "做种竞争度过高"
)
Variables ¶
This section is empty.
Functions ¶
func ComputeTier ¶ added in v0.35.0
func ComputeTier(state *models.SiteLoginState, effective, now time.Time) string
ComputeTier maps DaysRemaining into one of the predefined tier strings. The tier defines both the reminder urgency and whether quiet hours can be overridden (only banned-imminent overrides).
func DaysRemaining ¶ added in v0.35.0
func DaysRemaining(state *models.SiteLoginState, effective, now time.Time) int
DaysRemaining returns how many full days remain until the site's configured ban threshold elapses since the effective last-active time. Negative values mean the threshold has already been crossed.
func EffectiveLastActive ¶ added in v0.35.0
EffectiveLastActive returns the most recent confirmed activity timestamp for a site.
Per research: site cleanup.php scripts predominantly check `last_access` (NexusPHP) / `last_action` (Unit3D) / `LastAccess` (Gazelle) / `lastModifiedDate` (mTorrent) — NOT `last_login`. So v2 prefers last_access-class timestamps and treats last_login-class timestamps (ApiLastLoginAt, CookieLastLoginAt) as supplementary signals, used only when last_access is missing.
Precedence:
- state.LastAccessAt (NexusPHP last_access; primary)
- max(state.ApiLastLoginAt, state.CookieLastLoginAt) (R-Q-A5: take newer of dual timestamps)
- state.LastLoginAt (legacy v1 field)
- state.LastVisitAt (extension visit; only when probes failing >12h)
- zero value (no signal yet)
Types ¶
type CleanupMonitor ¶ added in v0.14.0
type CleanupMonitor struct {
// contains filtered or unexported fields
}
func NewCleanupMonitor ¶ added in v0.14.0
func NewCleanupMonitor(db *gorm.DB, downloaderMgr *downloader.DownloaderManager) *CleanupMonitor
func (*CleanupMonitor) RunManual ¶ added in v0.14.0
func (c *CleanupMonitor) RunManual() (int, error)
func (*CleanupMonitor) Start ¶ added in v0.14.0
func (c *CleanupMonitor) Start() error
func (*CleanupMonitor) Stop ¶ added in v0.14.0
func (c *CleanupMonitor) Stop()
type CredentialDecryptor ¶ added in v0.35.0
type CredentialDecryptor interface {
Decrypt(setting models.SiteSetting) (cookie string, err error)
}
CredentialDecryptor returns a usable cookie/api-key for a site. Real implementations decrypt SiteSetting.CookieEncrypted via core.ConfigStore; tests inject deterministic values.
type CronExpr ¶ added in v0.35.0
type CronExpr struct {
// contains filtered or unexported fields
}
CronExpr is a tiny 5-field cron evaluator (minute hour dom month dow) covering the patterns used by LoginReminderMonitor:
- Numeric value: "10", "22"
- Comma list: "10,22"
- Wildcard: "*"
- Step: "*/5", "*/15"
- Range: "1-5"
Day-of-week uses 0-6 with 0=Sunday (the standard cron convention). This is intentionally NOT a full cron implementation — it is purpose-built for reminder schedules and rejects unsupported syntax with a parse error so misconfigurations fail loud at config time, not silently at midnight.
func (*CronExpr) Match ¶ added in v0.35.0
Match reports whether the given time falls exactly on a cron tick (minute granularity). It does NOT consider seconds.
func (*CronExpr) WindowStart ¶ added in v0.35.0
WindowStart returns the most recent cron tick at or before t. The boundary is used by reminder dedup: two events that map to the same WindowStart are considered the same window and at most one reminder fires per window.
type FreeEndMonitor ¶ added in v0.3.0
type FreeEndMonitor struct {
// contains filtered or unexported fields
}
func NewFreeEndMonitor ¶ added in v0.3.0
func NewFreeEndMonitor(db *gorm.DB, downloaderMgr *downloader.DownloaderManager) *FreeEndMonitor
func (*FreeEndMonitor) CancelTorrent ¶ added in v0.3.0
func (m *FreeEndMonitor) CancelTorrent(torrentID uint)
func (*FreeEndMonitor) ScheduleTorrent ¶ added in v0.3.0
func (m *FreeEndMonitor) ScheduleTorrent(torrent models.TorrentInfo)
func (*FreeEndMonitor) Start ¶ added in v0.3.0
func (m *FreeEndMonitor) Start() error
func (*FreeEndMonitor) Stop ¶ added in v0.3.0
func (m *FreeEndMonitor) Stop()
func (*FreeEndMonitor) TestHandleFreeEndedTorrent ¶ added in v0.3.0
func (m *FreeEndMonitor) TestHandleFreeEndedTorrent(torrent models.TorrentInfo)
TestHandleFreeEndedTorrent 暴露给测试/调试命令使用
type LoginReminderConfig ¶ added in v0.35.0
type LoginReminderConfig struct {
DB *gorm.DB
Router *notify.Router
Resolver SiteResolver
Decryptor CredentialDecryptor
Clock sitelogin.Clock
Logger *zap.SugaredLogger
QuietHours QuietHours
ProbeEvery time.Duration
ReminderTick time.Duration
}
LoginReminderConfig holds the dependencies needed to construct a LoginReminderMonitor. All fields are required except QuietHours, which defaults to "no quiet window".
type LoginReminderMonitor ¶ added in v0.35.0
type LoginReminderMonitor struct {
// contains filtered or unexported fields
}
LoginReminderMonitor runs two cooperating loops:
probe loop (every 6h, per-site jitter): calls sitelogin.Probe() and persists last_login/last_access into models.SiteLoginState. On consecutive failure it backs off and after 24h emits a "cookie may have expired" warning notification.
reminder loop (every minute): for each enabled site whose effective last-active time is within (BanThresholdDays - RemindBeforeDays) of today, it computes a tier and fires a notification through notify.Router. Dedup is window-based (see CronExpr.WindowStart): within the same cron window only one reminder is sent, but a tier escalation immediately re-fires regardless of window.
The monitor never issues raw HTTP itself; all site I/O passes through the site/v2 driver layer (which inherits the project's circuit breaker and rate limiter).
func NewLoginReminderMonitor ¶ added in v0.35.0
func NewLoginReminderMonitor(cfg LoginReminderConfig) *LoginReminderMonitor
NewLoginReminderMonitor builds a LoginReminderMonitor. It does not start the loops; call Start to begin processing.
func (*LoginReminderMonitor) RunProbeOnce ¶ added in v0.35.0
func (m *LoginReminderMonitor) RunProbeOnce(ctx context.Context)
RunProbeOnce iterates enabled sites, probes each, and persists the result. It is exported so tests can drive the probe phase directly with a fake clock. This is cron-driven (manualTrigger=false). Sites whose probe slot is held by another trigger source (manual REST / extension push) are skipped this iteration with a debug log — R23 shared single-flight.
func (*LoginReminderMonitor) RunProbeOnceForSite ¶ added in v0.35.0
func (m *LoginReminderMonitor) RunProbeOnceForSite(ctx context.Context, siteName string) bool
RunProbeOnceForSite probes a single site by name. Used for manual endpoint triggering (manualTrigger=true), bypassing mode restrictions. Acquires the shared probe lock; returns false if another caller already holds it.
func (*LoginReminderMonitor) RunProbeOnceForSiteLocked ¶ added in v0.35.0
func (m *LoginReminderMonitor) RunProbeOnceForSiteLocked(ctx context.Context, siteName string)
RunProbeOnceForSiteLocked runs the probe assuming the caller already holds the per-site probe lock (via TryAcquireProbeLock). The web handler uses this split so the HTTP layer can shape its 409 response from TryAcquireProbeLock before dispatching the actual probe work.
func (*LoginReminderMonitor) RunReminderOnce ¶ added in v0.35.0
func (m *LoginReminderMonitor) RunReminderOnce(ctx context.Context)
RunReminderOnce iterates enabled sites, computes each site's tier, and fires reminders that are due. Exported for testability.
func (*LoginReminderMonitor) SendTestReminder ¶ added in v0.35.0
func (m *LoginReminderMonitor) SendTestReminder(ctx context.Context, siteName string) error
SendTestReminder immediately sends a test login-reminder notification for one site.
func (*LoginReminderMonitor) Start ¶ added in v0.35.0
func (m *LoginReminderMonitor) Start()
Start launches the probe and reminder loops. Calling Start twice is a no-op.
func (*LoginReminderMonitor) Stop ¶ added in v0.35.0
func (m *LoginReminderMonitor) Stop()
Stop signals both loops to exit and waits for them to drain.
func (*LoginReminderMonitor) TryAcquireProbeLock ¶ added in v0.35.0
func (m *LoginReminderMonitor) TryAcquireProbeLock(siteName string) (release func(), ok bool)
TryAcquireProbeLock attempts to acquire the per-site probe mutex without blocking. Returns (release, true) on success — caller MUST invoke release() in defer to free the slot. Returns (nil, false) if another caller (cron, REST, or extension) already holds the mutex; the caller should surface a 409-style "probe in progress" response. R23: this single map is the shared single-flight registry across all probe trigger sources.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
func NewManager ¶
func NewManager() *Manager
func (*Manager) GetDownloaderManager ¶ added in v0.2.0
func (m *Manager) GetDownloaderManager() *downloader.DownloaderManager
GetDownloaderManager 获取下载器管理器
func (*Manager) GetFreeEndMonitor ¶ added in v0.3.0
func (m *Manager) GetFreeEndMonitor() *FreeEndMonitor
GetFreeEndMonitor 获取免费结束监控器
func (*Manager) GetLoginReminderMonitor ¶ added in v0.35.0
func (m *Manager) GetLoginReminderMonitor() *LoginReminderMonitor
GetLoginReminderMonitor returns the registered monitor, or nil if not yet wired. Used by web handlers that want to trigger ad-hoc probes.
func (*Manager) InitFreeEndMonitor ¶ added in v0.3.0
func (m *Manager) InitFreeEndMonitor()
func (*Manager) LastVersion ¶
func (*Manager) SetLoginReminderMonitor ¶ added in v0.35.0
func (m *Manager) SetLoginReminderMonitor(mon *LoginReminderMonitor)
SetLoginReminderMonitor wires a fully-constructed LoginReminderMonitor into the manager. It is intended to be called by the web layer after the monitor has been built with a SiteResolver that knows how to produce v2.Site instances. Calling this twice replaces and stops the previous instance. Pass nil to detach without stopping.
type PeerRatioMonitor ¶ added in v0.23.0
type PeerRatioMonitor struct {
// contains filtered or unexported fields
}
func NewPeerRatioMonitor ¶ added in v0.23.0
func NewPeerRatioMonitor(db *gorm.DB, downloaderMgr *downloader.DownloaderManager) *PeerRatioMonitor
func (*PeerRatioMonitor) Start ¶ added in v0.23.0
func (p *PeerRatioMonitor) Start() error
func (*PeerRatioMonitor) Stop ¶ added in v0.23.0
func (p *PeerRatioMonitor) Stop()
type QuietHours ¶ added in v0.35.0
QuietHours represents the system-wide quiet window for non-critical notifications. Time strings use 24h "HH:MM" format. Empty start/end disables the window. The banned-imminent tier overrides quiet hours.
type SiteResolver ¶ added in v0.35.0
type SiteResolver interface {
Resolve(setting models.SiteSetting) (*v2.SiteDefinition, v2.Site, error)
}
SiteResolver wires a SiteSetting row into a v2.Site instance plus its SiteDefinition. It is injected so that tests can substitute fake sites without touching the global site registry or HTTP layer.