Plan B support torrent stabilization without starting

This commit is contained in:
Cœur 2023-02-14 20:50:05 +08:00
parent aa9e8daa4a
commit 603f78153f
5 changed files with 66 additions and 10 deletions

View File

@ -1339,6 +1339,7 @@ tr_stat tr_torrent::stats() const
stats.desiredAvailable = tr_peerMgrGetDesiredAvailable(this);
stats.ratio = tr_getRatio(stats.uploadedEver, this->size_when_done());
stats.startWhenStable = this->start_when_stable_;
auto seed_ratio_bytes_left = uint64_t{};
auto seed_ratio_bytes_goal = uint64_t{};
@ -1536,6 +1537,14 @@ void tr_torrentStartNow(tr_torrent* tor)
}
}
void tr_torrentStabilize(tr_torrent* tor)
{
if (tr_isTorrent(tor))
{
tor->start(!tor->has_metainfo(), {});
}
}
// ---
void tr_torrentVerify(tr_torrent* tor)

View File

@ -588,6 +588,9 @@ void tr_sessionSetAntiBruteForceEnabled(tr_session* session, bool enabled);
/** @brief Like `tr_torrentStart()`, but resumes right away regardless of the queues. */
void tr_torrentStartNow(tr_torrent* tor);
/** @brief Like `tr_torrentStart()`, but doesn't modify `start_when_stable`. */
void tr_torrentStabilize(tr_torrent* tor);
/** @brief Return the queued torrent's position in the queue it's in. [0...n) */
size_t tr_torrentGetQueuePosition(tr_torrent const* tor);
@ -1543,6 +1546,9 @@ struct tr_stat
/** If seeding, number of seconds left until the idle time limit is reached. */
time_t etaIdle;
/** Non-paused */
bool startWhenStable;
/** What is this torrent doing right now? */
tr_torrent_activity activity;

View File

@ -709,6 +709,7 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
//load previous transfers
tr_ctor* ctor = tr_ctorNew(session);
tr_ctorSetPaused(ctor, TR_FORCE, true); // paused by default; unpause below after checking state history
auto const n_torrents = tr_sessionLoadTorrents(session, ctor);
tr_ctorFree(ctor);
@ -746,25 +747,36 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
// theoretical max without doing a lot of work
NSMutableArray* waitToStartTorrents = [NSMutableArray
arrayWithCapacity:((history.count > 0 && !self.fPauseOnLaunch) ? history.count - 1 : 0)];
NSMutableArray* waitToStabilizeTorrents = [NSMutableArray
arrayWithCapacity:((history.count > 0 && !self.fPauseOnLaunch) ? history.count - 1 : 0)];
Torrent* t = [[Torrent alloc] init];
for (NSDictionary* historyItem in history)
{
NSString* hash = historyItem[@"TorrentHash"];
if ([self.fTorrentHashes.allKeys containsObject:hash])
{
Torrent* torrent = self.fTorrentHashes[hash];
[t setResumeStatusForTorrent:torrent withHistory:historyItem forcePause:self.fPauseOnLaunch];
[torrent setResumeStatusWithHistory:historyItem forcePause:self.fPauseOnLaunch];
NSNumber* waitToStart;
if (!self.fPauseOnLaunch && (waitToStart = historyItem[@"WaitToStart"]) && waitToStart.boolValue)
if (!self.fPauseOnLaunch && [historyItem[@"WaitToStart"] boolValue])
{
[waitToStartTorrents addObject:torrent];
if ([historyItem[@"StartWhenStable"] boolValue])
{
[waitToStartTorrents addObject:torrent];
}
else
{
[waitToStabilizeTorrents addObject:torrent];
}
}
}
}
//now that all are loaded, let's set those in the queue to waiting
// now that all are loaded, let's set those in the queue to waiting
for (Torrent* torrent in waitToStabilizeTorrents)
{
[torrent stabilize];
}
for (Torrent* torrent in waitToStartTorrents)
{
[torrent startTransfer];

View File

@ -21,7 +21,7 @@ extern NSString* const kTorrentDidChangeGroupNotification;
lib:(tr_session*)lib;
- (instancetype)initWithTorrentStruct:(tr_torrent*)torrentStruct location:(NSString*)location lib:(tr_session*)lib;
- (instancetype)initWithMagnetAddress:(NSString*)address location:(NSString*)location lib:(tr_session*)lib;
- (void)setResumeStatusForTorrent:(Torrent*)torrent withHistory:(NSDictionary*)history forcePause:(BOOL)pause;
- (void)setResumeStatusWithHistory:(NSDictionary*)history forcePause:(BOOL)pause;
@property(nonatomic, readonly) NSDictionary* history;
@ -37,6 +37,7 @@ extern NSString* const kTorrentDidChangeGroupNotification;
- (void)update;
- (void)stabilize;
- (void)startTransferIgnoringQueue:(BOOL)ignoreQueue;
- (void)startTransferNoQueue;
- (void)startTransfer;
@ -126,6 +127,8 @@ extern NSString* const kTorrentDidChangeGroupNotification;
@property(nonatomic, readonly) CGFloat availableDesired;
/// True if non-paused.
@property(nonatomic, readonly) BOOL startWhenStable;
/// True if non-paused. Running.
@property(nonatomic, getter=isActive, readonly) BOOL active;
/// True if downloading or uploading.

View File

@ -147,10 +147,23 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
return self;
}
- (void)setResumeStatusForTorrent:(Torrent*)torrent withHistory:(NSDictionary*)history forcePause:(BOOL)pause
- (void)setResumeStatusWithHistory:(NSDictionary*)history forcePause:(BOOL)pause
{
//restore GroupValue
torrent.groupValue = [history[@"GroupValue"] intValue];
// restore GroupValue
self.groupValue = [history[@"GroupValue"] intValue];
// start transfer
if (!pause && [history[@"Active"] boolValue])
{
if ([history[@"StartWhenStable"] boolValue])
{
[self startTransferNoQueue];
}
else
{
[self stabilize];
}
}
NSNumber* ratioLimit;
if ((ratioLimit = history[@"RatioLimit"]))
@ -165,6 +178,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
@"TorrentHash" : self.hashString,
@"Active" : @(self.active),
@"WaitToStart" : @(self.waitingToStart),
@"StartWhenStable" : @(self.startWhenStable),
@"GroupValue" : @(self.groupValue),
@"RemoveWhenFinishSeeding" : @(_removeWhenFinishSeeding)
};
@ -251,6 +265,12 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
}
}
- (void)stabilize
{
tr_torrentStabilize(self.fHandle);
[self update];
}
- (void)startTransferIgnoringQueue:(BOOL)ignoreQueue
{
if ([self alertForRemainingDiskSpace])
@ -439,6 +459,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
{
return tr_torrentGetPeerLimit(self.fHandle);
}
- (BOOL)waitingToStart
{
return self.fStat->activity == TR_STATUS_DOWNLOAD_WAIT || self.fStat->activity == TR_STATUS_SEED_WAIT;
@ -862,6 +883,11 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
return (CGFloat)self.fStat->desiredAvailable / self.sizeLeft;
}
- (BOOL)startWhenStable
{
return self.fStat->startWhenStable;
}
- (BOOL)isActive
{
return self.fStat->activity != TR_STATUS_STOPPED && self.fStat->activity != TR_STATUS_DOWNLOAD_WAIT &&