Skip to content

Commit

Permalink
downloader: handle race between adding magnet link and files from web…
Browse files Browse the repository at this point in the history
…seed (#9045)
  • Loading branch information
AskAlexSharov authored Dec 21, 2023
1 parent 8c82225 commit 56c5f65
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
10 changes: 6 additions & 4 deletions erigon-lib/downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func (d *Downloader) AddNewSeedableFile(ctx context.Context, name string) error
if err != nil {
return fmt.Errorf("AddNewSeedableFile: %w", err)
}
err = addTorrentFile(ctx, ts, d.torrentClient, d.webseeds)
_, _, err = addTorrentFile(ctx, ts, d.torrentClient, d.webseeds)
if err != nil {
return fmt.Errorf("addTorrentFile: %w", err)
}
Expand Down Expand Up @@ -619,11 +619,13 @@ func (d *Downloader) AddMagnetLink(ctx context.Context, infoHash metainfo.Hash,
if err != nil {
return err
}
spec.DisallowDataDownload = true
t, _, err := d.torrentClient.AddTorrentSpec(spec)
t, ok, err := addTorrentFile(ctx, spec, d.torrentClient, d.webseeds)
if err != nil {
return err
}
if !ok {
return nil
}
d.wg.Add(1)
go func(t *torrent.Torrent) {
defer d.wg.Done()
Expand Down Expand Up @@ -672,7 +674,7 @@ func (d *Downloader) addTorrentFilesFromDisk(quiet bool) error {
return err
}
for i, ts := range files {
err := addTorrentFile(d.ctx, ts, d.torrentClient, d.webseeds)
_, _, err := addTorrentFile(d.ctx, ts, d.torrentClient, d.webseeds)
if err != nil {
return err
}
Expand Down
59 changes: 43 additions & 16 deletions erigon-lib/downloader/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,29 +306,56 @@ func loadTorrent(torrentFilePath string) (*torrent.TorrentSpec, error) {
// added first time - pieces verification process will start (disk IO heavy) - Progress
// kept in `piece completion storage` (surviving reboot). Once it done - no disk IO needed again.
// Don't need call torrent.VerifyData manually
func addTorrentFile(ctx context.Context, ts *torrent.TorrentSpec, torrentClient *torrent.Client, webseeds *WebSeeds) error {
func addTorrentFile(ctx context.Context, ts *torrent.TorrentSpec, torrentClient *torrent.Client, webseeds *WebSeeds) (t *torrent.Torrent, ok bool, err error) {
ts.ChunkSize = downloadercfg.DefaultNetworkChunkSize
ts.DisallowDataDownload = true
ts.DisableInitialPieceCheck = true
//re-try on panic, with 0 ChunkSize (lib doesn't allow change this field for existing torrents)
defer func() {
rec := recover()
if rec != nil {
ts.ChunkSize = 0
t, ok, err = _addTorrentFile(ctx, ts, torrentClient, webseeds)
}
}()

t, ok, err = _addTorrentFile(ctx, ts, torrentClient, webseeds)
if err != nil {
ts.ChunkSize = 0
return _addTorrentFile(ctx, ts, torrentClient, webseeds)
}
return t, ok, err
}

func _addTorrentFile(ctx context.Context, ts *torrent.TorrentSpec, torrentClient *torrent.Client, webseeds *WebSeeds) (t *torrent.Torrent, ok bool, err error) {
select {
case <-ctx.Done():
return ctx.Err()
return nil, false, ctx.Err()
default:
}
wsUrls, ok := webseeds.ByFileName(ts.DisplayName)
if ok {
ts.Webseeds = append(ts.Webseeds, wsUrls...)
}

_, ok = torrentClient.Torrent(ts.InfoHash)
if !ok { // can set ChunkSize only for new torrents
ts.ChunkSize = downloadercfg.DefaultNetworkChunkSize
} else {
ts.ChunkSize = 0
ts.Webseeds, _ = webseeds.ByFileName(ts.DisplayName)
var have bool
t, have = torrentClient.Torrent(ts.InfoHash)
if !have {
t, _, err := torrentClient.AddTorrentSpec(ts)
if err != nil {
return nil, false, fmt.Errorf("addTorrentFile %s: %w", ts.DisplayName, err)
}
return t, true, nil
}
ts.DisallowDataDownload = true
_, _, err := torrentClient.AddTorrentSpec(ts)
if err != nil {
return fmt.Errorf("addTorrentFile %s: %w", ts.DisplayName, err)

select {
case <-t.GotInfo():
t.AddWebSeeds(ts.Webseeds)
default:
t, _, err = torrentClient.AddTorrentSpec(ts)
if err != nil {
return nil, false, fmt.Errorf("addTorrentFile %s: %w", ts.DisplayName, err)
}
}
return nil

return t, true, nil
}

func savePeerID(db kv.RwDB, peerID torrent.PeerID) error {
Expand Down

0 comments on commit 56c5f65

Please sign in to comment.