mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-09 01:50:30 +00:00
perf: excessive torrent tracker dns resolve (#634)
This commit is contained in:
7 files changed
+239
-149
No files matched your search
+58
-33
@@ -63,6 +63,7 @@ type Downloader struct {
|
||||
storage Storage
|
||||
tasks []*Task
|
||||
waitTasks []*Task
|
||||
watchedTasks sync.Map
|
||||
listener Listener
|
||||
|
||||
lock *sync.Mutex
|
||||
@@ -170,7 +171,7 @@ func (d *Downloader) Setup() error {
|
||||
go func() {
|
||||
for _, task := range d.tasks {
|
||||
if task.Status == base.DownloadStatusDone && task.Uploading {
|
||||
if err := d.restoreFetcher(task); err != nil {
|
||||
if err := d.restoreTask(task); err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("task upload restore fetcher failed, task id: %s", task.ID)
|
||||
}
|
||||
if uploader, ok := task.fetcher.(fetcher.Uploader); ok {
|
||||
@@ -530,6 +531,17 @@ func (d *Downloader) Stats(id string) (sr any, err error) {
|
||||
if task == nil {
|
||||
return sr, ErrTaskNotFound
|
||||
}
|
||||
if task.fetcher == nil {
|
||||
err = func() error {
|
||||
task.statusLock.Lock()
|
||||
defer task.statusLock.Unlock()
|
||||
|
||||
return d.restoreFetcher(task)
|
||||
}()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
sr = task.fetcher.Stats()
|
||||
return
|
||||
}
|
||||
@@ -681,6 +693,14 @@ func (d *Downloader) getProtocolConfig(name string, v any) bool {
|
||||
|
||||
// wait task done
|
||||
func (d *Downloader) watch(task *Task) {
|
||||
if _, loaded := d.watchedTasks.LoadOrStore(task.ID, true); loaded {
|
||||
return
|
||||
}
|
||||
|
||||
defer func() {
|
||||
d.watchedTasks.Delete(task.ID)
|
||||
}()
|
||||
|
||||
// wait task upload done
|
||||
if task.Uploading {
|
||||
if uploader, ok := task.fetcher.(fetcher.Uploader); ok {
|
||||
@@ -759,42 +779,47 @@ func (d *Downloader) doOnError(task *Task, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) restoreFetcher(task *Task) error {
|
||||
func (d *Downloader) restoreTask(task *Task) error {
|
||||
if task.fetcher == nil {
|
||||
fm, err := d.parseFm(task.Meta.Req.URL)
|
||||
if err := d.restoreFetcher(task); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
go d.watch(task)
|
||||
task.fetcher.Create(task.Meta.Opts)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Downloader) restoreFetcher(task *Task) error {
|
||||
var fm fetcher.FetcherManager
|
||||
for _, f := range d.cfg.FetchManagers {
|
||||
if f.Name() == task.Protocol {
|
||||
fm = f
|
||||
break
|
||||
}
|
||||
}
|
||||
if fm == nil {
|
||||
return ErrUnSupportedProtocol
|
||||
}
|
||||
task.fetcherManager = fm
|
||||
v, f := fm.Restore()
|
||||
if v != nil {
|
||||
err := d.storage.Pop(bucketSave, task.ID, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.fetcherManager = fm
|
||||
err = func() error {
|
||||
v, f := fm.Restore()
|
||||
if v != nil {
|
||||
err := d.storage.Pop(bucketSave, task.ID, v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
task.fetcher = f(task.Meta, v)
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("deserialize fetcher failed, task id: %s", task.ID)
|
||||
}
|
||||
if task.fetcher == nil {
|
||||
task.fetcher = fm.Build()
|
||||
}
|
||||
d.setupFetcher(fm, task.fetcher)
|
||||
if task.fetcher.Meta().Req == nil {
|
||||
task.fetcher.Meta().Req = task.Meta.Req
|
||||
}
|
||||
if task.fetcher.Meta().Res == nil {
|
||||
task.fetcher.Meta().Res = task.Meta.Res
|
||||
}
|
||||
go d.watch(task)
|
||||
} else if task.Status == base.DownloadStatusError {
|
||||
go d.watch(task)
|
||||
}
|
||||
task.fetcher.Create(task.Meta.Opts)
|
||||
task.fetcher = f(task.Meta, v)
|
||||
if task.fetcher == nil {
|
||||
task.fetcher = task.fetcherManager.Build()
|
||||
}
|
||||
d.setupFetcher(task.fetcherManager, task.fetcher)
|
||||
if task.fetcher.Meta().Req == nil {
|
||||
task.fetcher.Meta().Req = task.Meta.Req
|
||||
}
|
||||
if task.fetcher.Meta().Res == nil {
|
||||
task.fetcher.Meta().Res = task.Meta.Res
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -872,7 +897,7 @@ func (d *Downloader) doStart(task *Task) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
err = d.restoreFetcher(task)
|
||||
err = d.restoreTask(task)
|
||||
if err != nil {
|
||||
d.Logger.Error().Stack().Err(err).Msgf("restore fetcher failed, task id: %s", task.ID)
|
||||
return
|
||||
|
||||
+5
-5
@@ -13,12 +13,12 @@ import (
|
||||
|
||||
func Info(w http.ResponseWriter, r *http.Request) {
|
||||
info := map[string]any{
|
||||
"version": base.Version,
|
||||
"runtime": runtime.Version(),
|
||||
"os": runtime.GOOS,
|
||||
"arch": runtime.GOARCH,
|
||||
"version": base.Version,
|
||||
"runtime": runtime.Version(),
|
||||
"os": runtime.GOOS,
|
||||
"arch": runtime.GOARCH,
|
||||
"inDocker": base.InDocker == "true",
|
||||
}
|
||||
info["inDocker"] = base.InDocker == "true"
|
||||
WriteJson(w, model.NewOkResult(info))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user