Add repair all trigger
This commit is contained in:
@@ -206,21 +206,13 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
|
|||||||
<td>Can Repair</td>
|
<td>Can Repair</td>
|
||||||
<td>%t</td>
|
<td>%t</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>Repair Every...</td>
|
|
||||||
<td>%d mins</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Action to take on RAR'ed torrents</td>
|
<td>Action to take on RAR'ed torrents</td>
|
||||||
<td>%s</td>
|
<td>%s</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>API Timeout</td>
|
<td>Repair Every...</td>
|
||||||
<td>%d secs</td>
|
<td>%d mins</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Download Timeout</td>
|
|
||||||
<td>%d secs</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Refresh Download Mount Every...</td>
|
<td>Refresh Download Mount Every...</td>
|
||||||
@@ -230,6 +222,14 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
|
|||||||
<td>Dump Torrents Every...</td>
|
<td>Dump Torrents Every...</td>
|
||||||
<td>%d mins</td>
|
<td>%d mins</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>API Timeout</td>
|
||||||
|
<td>%d secs</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Download Timeout</td>
|
||||||
|
<td>%d secs</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Rate Limit Sleep for...</td>
|
<td>Rate Limit Sleep for...</td>
|
||||||
<td>%d secs</td>
|
<td>%d secs</td>
|
||||||
@@ -286,6 +286,9 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
|
|||||||
<form method="post" action="/torrents/analyze">
|
<form method="post" action="/torrents/analyze">
|
||||||
<input type="submit" value="Analyze torrents" />
|
<input type="submit" value="Analyze torrents" />
|
||||||
</form>
|
</form>
|
||||||
|
<form method="post" action="/torrents/repair">
|
||||||
|
<input type="submit" value="Repair torrents" />
|
||||||
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -331,12 +334,12 @@ func (zr *Handlers) handleHome(resp http.ResponseWriter, req *http.Request) {
|
|||||||
response.Config.EnableRetainRDTorrentName(),
|
response.Config.EnableRetainRDTorrentName(),
|
||||||
response.Config.EnableRetainFolderNameExtension(),
|
response.Config.EnableRetainFolderNameExtension(),
|
||||||
response.Config.EnableRepair(),
|
response.Config.EnableRepair(),
|
||||||
response.Config.GetRepairEveryMins(),
|
|
||||||
response.Config.GetRarAction(),
|
response.Config.GetRarAction(),
|
||||||
response.Config.GetApiTimeoutSecs(),
|
response.Config.GetRepairEveryMins(),
|
||||||
response.Config.GetDownloadTimeoutSecs(),
|
|
||||||
response.Config.GetDownloadsEveryMins(),
|
response.Config.GetDownloadsEveryMins(),
|
||||||
response.Config.GetDumpTorrentsEveryMins(),
|
response.Config.GetDumpTorrentsEveryMins(),
|
||||||
|
response.Config.GetApiTimeoutSecs(),
|
||||||
|
response.Config.GetDownloadTimeoutSecs(),
|
||||||
response.Config.GetRateLimitSleepSecs(),
|
response.Config.GetRateLimitSleepSecs(),
|
||||||
response.Config.GetRetriesUntilFailed(),
|
response.Config.GetRetriesUntilFailed(),
|
||||||
response.Config.GetNetworkBufferSize(),
|
response.Config.GetNetworkBufferSize(),
|
||||||
@@ -360,7 +363,7 @@ func (zr *Handlers) handleRebootWorkerPool(resp http.ResponseWriter, req *http.R
|
|||||||
|
|
||||||
func (zr *Handlers) handleRebootRefreshWorker(resp http.ResponseWriter, req *http.Request) {
|
func (zr *Handlers) handleRebootRefreshWorker(resp http.ResponseWriter, req *http.Request) {
|
||||||
resp.Header().Set("Refresh", "2; url=/")
|
resp.Header().Set("Refresh", "2; url=/")
|
||||||
zr.torMgr.RefreshKillSwitch <- struct{}{}
|
zr.torMgr.RefreshWorkerKillSwitch <- struct{}{}
|
||||||
zr.torMgr.StartRefreshJob()
|
zr.torMgr.StartRefreshJob()
|
||||||
zr.log.Infof("Rebooted refresh worker")
|
zr.log.Infof("Rebooted refresh worker")
|
||||||
fmt.Fprint(resp, "Rebooting refresh worker...")
|
fmt.Fprint(resp, "Rebooting refresh worker...")
|
||||||
@@ -368,7 +371,7 @@ func (zr *Handlers) handleRebootRefreshWorker(resp http.ResponseWriter, req *htt
|
|||||||
|
|
||||||
func (zr *Handlers) handleRebootRepairWorker(resp http.ResponseWriter, req *http.Request) {
|
func (zr *Handlers) handleRebootRepairWorker(resp http.ResponseWriter, req *http.Request) {
|
||||||
resp.Header().Set("Refresh", "2; url=/")
|
resp.Header().Set("Refresh", "2; url=/")
|
||||||
zr.torMgr.RepairKillSwitch <- struct{}{}
|
zr.torMgr.RepairWorkerKillSwitch <- struct{}{}
|
||||||
zr.torMgr.StartRepairJob()
|
zr.torMgr.StartRepairJob()
|
||||||
zr.log.Infof("Rebooted repair worker")
|
zr.log.Infof("Rebooted repair worker")
|
||||||
fmt.Fprint(resp, "Rebooting repair worker...")
|
fmt.Fprint(resp, "Rebooting repair worker...")
|
||||||
@@ -395,6 +398,13 @@ func (zr *Handlers) handleAnalyzeTorrents(resp http.ResponseWriter, req *http.Re
|
|||||||
fmt.Fprint(resp, "Analyzing all torrents...")
|
fmt.Fprint(resp, "Analyzing all torrents...")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (zr *Handlers) handleTriggerRepairAll(resp http.ResponseWriter, req *http.Request) {
|
||||||
|
resp.Header().Set("Refresh", "2; url=/")
|
||||||
|
zr.torMgr.RepairAllTrigger <- struct{}{}
|
||||||
|
zr.log.Infof("Triggered repair of all torrents")
|
||||||
|
fmt.Fprint(resp, "Repairing all torrents...")
|
||||||
|
}
|
||||||
|
|
||||||
func bToMb(b uint64) uint64 {
|
func bToMb(b uint64) uint64 {
|
||||||
return b / 1024 / 1024
|
return b / 1024 / 1024
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ func AttachHandlers(router *chi.Mux, downloader *universal.Downloader, torMgr *t
|
|||||||
router.Post("/downloads/remount", hs.handleRemountDownloads)
|
router.Post("/downloads/remount", hs.handleRemountDownloads)
|
||||||
router.Post("/torrents/dump", hs.handleDumpTorrents)
|
router.Post("/torrents/dump", hs.handleDumpTorrents)
|
||||||
router.Post("/torrents/analyze", hs.handleAnalyzeTorrents)
|
router.Post("/torrents/analyze", hs.handleAnalyzeTorrents)
|
||||||
|
router.Post("/torrents/repair", hs.handleTriggerRepairAll)
|
||||||
// version
|
// version
|
||||||
router.Get(fmt.Sprintf("/{mountType}/%s", version.FILE), hs.handleVersionFile)
|
router.Get(fmt.Sprintf("/{mountType}/%s", version.FILE), hs.handleVersionFile)
|
||||||
router.Head(fmt.Sprintf("/{mountType}/%s", version.FILE), hs.handleCheckVersionFile)
|
router.Head(fmt.Sprintf("/{mountType}/%s", version.FILE), hs.handleCheckVersionFile)
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ func (t *TorrentManager) binOnceDoneErrorCheck(torrentId, status string) bool {
|
|||||||
if status == "downloading" || status == "downloaded" || status == "uploading" || status == "queued" || status == "compressing" || status == "waiting_files_selection" {
|
if status == "downloading" || status == "downloaded" || status == "uploading" || status == "queued" || status == "compressing" || status == "waiting_files_selection" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
t.repairLog.Errorf("Bin: error status=%s, checking if %s should be deleted", status, torrentId)
|
t.repairLog.Infof("Bin: error status=%s, checking if %s should be deleted", status, torrentId)
|
||||||
return t.binOnceDone(torrentId, true)
|
return t.binOnceDone(torrentId, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,10 @@ type TorrentManager struct {
|
|||||||
|
|
||||||
RootNode *fs.FileNode
|
RootNode *fs.FileNode
|
||||||
|
|
||||||
RefreshKillSwitch chan struct{}
|
RefreshWorkerKillSwitch chan struct{}
|
||||||
RepairKillSwitch chan struct{}
|
RepairWorkerKillSwitch chan struct{}
|
||||||
RemountTrigger chan struct{}
|
RemountTrigger chan struct{}
|
||||||
|
RepairAllTrigger chan struct{}
|
||||||
DumpTrigger chan struct{}
|
DumpTrigger chan struct{}
|
||||||
AnalyzeTrigger chan struct{}
|
AnalyzeTrigger chan struct{}
|
||||||
|
|
||||||
@@ -76,9 +77,10 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
|
|||||||
|
|
||||||
RootNode: fs.NewFileNode("root", true),
|
RootNode: fs.NewFileNode("root", true),
|
||||||
|
|
||||||
RefreshKillSwitch: make(chan struct{}, 1),
|
RefreshWorkerKillSwitch: make(chan struct{}, 1),
|
||||||
RepairKillSwitch: make(chan struct{}, 1),
|
RepairWorkerKillSwitch: make(chan struct{}, 1),
|
||||||
RemountTrigger: make(chan struct{}, 1),
|
RemountTrigger: make(chan struct{}, 1),
|
||||||
|
// RepairAllTrigger: make(chan struct{}, 1), // initialized in repair.go
|
||||||
DumpTrigger: make(chan struct{}, 1),
|
DumpTrigger: make(chan struct{}, 1),
|
||||||
AnalyzeTrigger: make(chan struct{}, 1),
|
AnalyzeTrigger: make(chan struct{}, 1),
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ func (t *TorrentManager) StartRefreshJob() {
|
|||||||
|
|
||||||
t.refreshTorrents(false)
|
t.refreshTorrents(false)
|
||||||
t.log.Info("Finished refreshing torrents")
|
t.log.Info("Finished refreshing torrents")
|
||||||
case <-t.RefreshKillSwitch:
|
case <-t.RefreshWorkerKillSwitch:
|
||||||
t.log.Info("Stopping periodic refresh job")
|
t.log.Info("Stopping periodic refresh job")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ func (t *TorrentManager) StartRepairJob() {
|
|||||||
}
|
}
|
||||||
t.repairTrigger = make(chan *Torrent)
|
t.repairTrigger = make(chan *Torrent)
|
||||||
t.repairQueue = mapset.NewSet[*Torrent]()
|
t.repairQueue = mapset.NewSet[*Torrent]()
|
||||||
|
t.RepairAllTrigger = make(chan struct{})
|
||||||
// there is 1 repair worker, with max 1 blocking task
|
// there is 1 repair worker, with max 1 blocking task
|
||||||
t.workerPool.Submit(func() {
|
t.workerPool.Submit(func() {
|
||||||
t.repairLog.Debug("Starting periodic repair job")
|
t.repairLog.Debug("Starting periodic repair job")
|
||||||
@@ -36,10 +37,12 @@ func (t *TorrentManager) StartRepairJob() {
|
|||||||
select {
|
select {
|
||||||
case <-repairTicker.C:
|
case <-repairTicker.C:
|
||||||
t.invokeRepair(nil)
|
t.invokeRepair(nil)
|
||||||
|
case <-t.RepairAllTrigger:
|
||||||
|
t.invokeRepair(nil)
|
||||||
case torrent := <-t.repairTrigger:
|
case torrent := <-t.repairTrigger:
|
||||||
// On-demand trigger with a specific torrent
|
// On-demand trigger with a specific torrent
|
||||||
t.invokeRepair(torrent)
|
t.invokeRepair(torrent)
|
||||||
case <-t.RepairKillSwitch:
|
case <-t.RepairWorkerKillSwitch:
|
||||||
t.repairLog.Info("Stopping periodic repair job")
|
t.repairLog.Info("Stopping periodic repair job")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -76,15 +79,19 @@ func (t *TorrentManager) invokeRepair(torrent *Torrent) {
|
|||||||
|
|
||||||
// TriggerRepair allows an on-demand repair to be initiated.
|
// TriggerRepair allows an on-demand repair to be initiated.
|
||||||
func (t *TorrentManager) TriggerRepair(torrent *Torrent) {
|
func (t *TorrentManager) TriggerRepair(torrent *Torrent) {
|
||||||
|
if !t.Config.EnableRepair() {
|
||||||
|
if torrent != nil {
|
||||||
|
t.repairLog.Warnf("Repair is disabled, skipping repair for torrent %s", t.GetKey(torrent))
|
||||||
|
} else {
|
||||||
|
t.repairLog.Warn("Repair is disabled, skipping repair")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
if torrent != nil {
|
if torrent != nil {
|
||||||
if err := torrent.State.Event(context.Background(), "break_torrent"); err != nil {
|
if err := torrent.State.Event(context.Background(), "break_torrent"); err != nil {
|
||||||
// t.repairLog.Errorf("Failed to mark torrent %s as broken: %v", t.GetKey(torrent), err)
|
// t.repairLog.Errorf("Failed to mark torrent %s as broken: %v", t.GetKey(torrent), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !t.Config.EnableRepair() {
|
|
||||||
t.repairLog.Warnf("Repair is disabled, skipping repair for torrent %s", t.GetKey(torrent))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
t.repairTrigger <- torrent
|
t.repairTrigger <- torrent
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user