-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
downloader: added downloaded torrents notifier #11850
Changes from 18 commits
eff2438
da7f5e7
cd91aa0
3d70db0
40aa539
8cd8d44
b425906
f1c656a
6f71fd1
42bb469
b72cbc9
4e8b4b0
dc05f64
ee52bc8
b84ab18
2e2c4c4
1d2e25b
ba451aa
d75e121
ac9b4ee
165232c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -59,6 +59,7 @@ import ( | |||
"github.com/erigontech/erigon-lib/diagnostics" | ||||
"github.com/erigontech/erigon-lib/downloader/downloadercfg" | ||||
"github.com/erigontech/erigon-lib/downloader/snaptype" | ||||
prototypes "github.com/erigontech/erigon-lib/gointerfaces/typesproto" | ||||
"github.com/erigontech/erigon-lib/kv" | ||||
"github.com/erigontech/erigon-lib/kv/mdbx" | ||||
"github.com/erigontech/erigon-lib/log/v3" | ||||
|
@@ -97,8 +98,15 @@ type Downloader struct { | |||
|
||||
stuckFileDetailedLogs bool | ||||
|
||||
logPrefix string | ||||
startTime time.Time | ||||
logPrefix string | ||||
startTime time.Time | ||||
broadcast func(name string, hash *prototypes.H160) | ||||
completedTorrents map[string]completedTorrentInfo | ||||
} | ||||
|
||||
type completedTorrentInfo struct { | ||||
path string | ||||
hash *prototypes.H160 | ||||
} | ||||
|
||||
type downloadInfo struct { | ||||
|
@@ -345,6 +353,7 @@ func New(ctx context.Context, cfg *downloadercfg.Cfg, logger log.Logger, verbosi | |||
downloading: map[string]*downloadInfo{}, | ||||
webseedsDiscover: discover, | ||||
logPrefix: "", | ||||
completedTorrents: make(map[string]completedTorrentInfo), | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This duplicates the info in downloading above and the info held locally in the local maps here: could you rationalize this so we end up with a single collection which is held by the downloader which keeps the whole download lifecycle. This is a rationalization which is well overdue - seems like as you are adding another collection it would be a good time to make this change. Note that you may need to protect access to this map with the downloader mutex There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not do this as at some point we are deleting from the erigon/erigon-lib/downloader/downloader.go Line 1110 in ba451aa
This meant that it may not contains completed parts and the I think such changes must be done as separate task as it will be to many changes to logic in the same PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is every time we add new collections it makes the code gradually more complex - I don't think the change is that big. You can just add a status with the following states complete to the downloadInfo struct them you only need one map. If you want to add more info you need to do the refactor. I'm ok if you do 2 PR's one with the refactor and the second adding the notifier - but I don't think we should make the code change like this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want to simplify the change you can just do complete. At the moment you are setting 2 variable with an external function doing the same thing here: complete[t.Name()] = struct{}{} I don't think you should add this code duplication. |
||||
} | ||||
d.webseeds.SetTorrent(d.torrentFS, snapLock.Downloads, cfg.DownloadTorrentFilesFromWebseed) | ||||
|
||||
|
@@ -906,6 +915,7 @@ func (d *Downloader) mainLoop(silent bool) error { | |||
for _, t := range torrents { | ||||
if _, ok := complete[t.Name()]; ok { | ||||
clist = append(clist, t.Name()) | ||||
d.torrentCompleted(t.Name(), t.InfoHash()) | ||||
continue | ||||
} | ||||
|
||||
|
@@ -959,6 +969,7 @@ func (d *Downloader) mainLoop(silent bool) error { | |||
} else { | ||||
clist = append(clist, t.Name()) | ||||
complete[t.Name()] = struct{}{} | ||||
d.torrentCompleted(t.Name(), t.InfoHash()) | ||||
continue | ||||
} | ||||
} | ||||
|
@@ -1025,6 +1036,8 @@ func (d *Downloader) mainLoop(silent bool) error { | |||
d.lock.Unlock() | ||||
complete[t.Name()] = struct{}{} | ||||
clist = append(clist, t.Name()) | ||||
d.torrentCompleted(t.Name(), t.InfoHash()) | ||||
|
||||
continue | ||||
} | ||||
|
||||
|
@@ -2762,6 +2775,7 @@ func (d *Downloader) BuildTorrentFilesIfNeed(ctx context.Context, chain string, | |||
_, err := BuildTorrentFilesIfNeed(ctx, d.cfg.Dirs, d.torrentFS, chain, ignore, false) | ||||
return err | ||||
} | ||||
|
||||
func (d *Downloader) Stats() AggStats { | ||||
d.lock.RLock() | ||||
defer d.lock.RUnlock() | ||||
|
@@ -2946,3 +2960,32 @@ func calculateTime(amountLeft, rate uint64) string { | |||
func (d *Downloader) Completed() bool { | ||||
return d.stats.Completed | ||||
} | ||||
|
||||
// Store completed torrents in order to notify GrpcServer subscribers when they subscribe and there is already downloaded files | ||||
func (d *Downloader) torrentCompleted(tName string, tHash metainfo.Hash) { | ||||
d.lock.Lock() | ||||
defer d.lock.Unlock() | ||||
hash := InfoHashes2Proto(tHash) | ||||
|
||||
//check is torrent already completed cause some funcs may call this method multiple times | ||||
if _, ok := d.completedTorrents[tName]; !ok { | ||||
d.notifyCompleted(tName, hash) | ||||
} | ||||
|
||||
d.completedTorrents[tName] = completedTorrentInfo{ | ||||
path: tName, | ||||
hash: hash, | ||||
} | ||||
} | ||||
|
||||
// Notify GrpcServer subscribers about completed torrent | ||||
func (d *Downloader) notifyCompleted(tName string, tHash *prototypes.H160) { | ||||
d.broadcast(tName, tHash) | ||||
} | ||||
|
||||
func (d *Downloader) getCompletedTorrents() map[string]completedTorrentInfo { | ||||
d.lock.RLock() | ||||
defer d.lock.RUnlock() | ||||
|
||||
return d.completedTorrents | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you rename this to notifyCompleted - you don't need an extra wrapper to call a function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done