Skip to content
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

Client locks up and never starts downloading if it has nothing to download at start #597

Closed
ManlyMarco opened this issue Jan 18, 2023 · 1 comment · Fixed by #601
Closed

Comments

@ManlyMarco
Copy link

ManlyMarco commented Jan 18, 2023

It looks like if the torrent has nothing to download for some time after it is started, it will lock up and never start downloading. It does connect to my seed for that torrent and keeps the connection active, but never actually downloads anything.

It doesn't matter if any files are finished and the torrent is seeding, or if nothing is downloaded yet. As long as there are no transfers for some time after starting, it just permanently dies.

I have 1 seed for the torrent (also using MonoTorrent) that is verified to work fine with qBittorrent. I can see on the seed that the client does in fact correctly connect to it but it never asks for any chunks.

How to reproduce:
The torrent needs a singular seed with an open port. It seems like the key is that the client has nothing to do and falls asleep forever.

// There is some unnecessry code but since the issue seems to be timing-dependant 
// and somewhat random I kept it all from when the issue seemed to be the most reliably reproduced
var t = await _source.Client.AddAsync(torrent, "e:\\test", new TorrentSettingsBuilder()
{
    CreateContainingDirectory = false,
    AllowInitialSeeding = true
}.ToSettings());

await t.WaitForMetadataAsync(cancellationToken);

// Not sure if necessary or not, probably not
await t.HashCheckAsync(false);

foreach (var f in t.Files)
{
    // Stop the torrent from downloading after starting. If some files are finished they can be left enabled.
    await t.SetFilePriorityAsync(f, Priority.DoNotDownload);
    // Not sure if necessary or not, probably not
    await t.MoveFileAsync(f, Path.Combine("e:\\test2", Path.GetRandomFileName()));
}

await t.StartAsync(); 

// This line causes the torrent to never start downloading from the seeder
await Task.Delay(20000);

foreach (var f in t.Files)
{
    // This should make the client start downloading
    await t.SetFilePriorityAsync(f, Priority.High);
}

// Adding these two "fixes" the issue but is not very practical
//await t.StopAsync();
//await t.StartAsync();

while (!t.Complete)
{
    await Task.Delay(1000);
    Console.WriteLine($"State={t.State} Progress={t.Progress} Seeds={t.Peers.Seeds}");
}

Confirmed on latest stable and on 3.0.0-beta.rev0106 releases.

@alanmcgovern
Copy link
Owner

That should be fixed now! This looks like an oversight. The original intent was to update the 'AmInterested' state of remote peers on an as-needed basis. Back in the day there were a limited number of ways the state could change, primarily when a message is sent/received: HaveAll/HaveNone/Have messages.

However, the engine got a little more advanced and there are some dynamic ways the status can change, i.e. files which were marked as DoNotDownload are now marked as Normal priority, or files which were pending a hashcheck have now been background hashed, or the v2 info hashes have now been received so some pieces can now be requested.

It's a bit harder to enumerate all possible cases now, so I just added a timed refresh. This kind of timed refresh is already performed to disconnect peers who are non-responsive so there was a convenient place for it.

Thanks for reporting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants