opt: downloader
#1003 反复重做,重开个pr。
- 使用平滑窗口平均 平滑速度计算、剩余时间估计。
- 在继续任务前,确保之前的任务线程均结束,避免文件被占用。
- 任务发生任何崩溃均将任务添加回_installItemQueue。
- 优化下载限速器
与当前限速器的区别:
- 精细化令牌补充间隔,避免流量全堆积在单位时间的开始、减少实际即时速度的误差。
- 不限速时不使用限流器,以减少性能消耗。
- 使用https://github.com/Scighost/Starward/pull/1019#issuecomment-2272553820 的方式实现精确控制速度,数据流恢复为16KB避免I/O过于频繁。
- 将限速设置的NumberBox上限设为2097151(int.MaxValue / 1024向下取整)
close #996 , close #997
@Scighost 打扰,但这个有时间看看可以merge了?(
可以试试这个
internal static class TokenBucketRateLimiterExtension
{
public static int Acquire(this TokenBucketRateLimiter rateLimiter, int permits, out TimeSpan retryAfter)
{
int count = Math.Min(permits, (int)Volatile.Read(ref PrivateGetTokenCount(rateLimiter)));
return rateLimiter.AttemptAcquire(count).TryGetMetadata(MetadataName.RetryAfter, out retryAfter) ? 0 : count;
}
// private double _tokenCount;
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_tokenCount")]
private static extern ref double PrivateGetTokenCount(TokenBucketRateLimiter rateLimiter);
}
可以试试这个
谢谢,好用,用了(
@Eric-Joker 我最终实际体验了一下还是改成了下面的样子
带count的Replenish方便返还 Read Span
Update:
返还 Read Span buffer 实际上没填充的字节数
emm?没太明白,现在的实现就是根据ReadAsync返回的值来租用令牌的
返还 Read Span buffer 实际上没填充的字节数
emm?没太明白,现在的实现就是根据ReadAsync返回的值来租用令牌的
我的实现是尝试获取buffer长度的令牌,然后再读的,由于读取的长度可能会比buffer小所以我加了返还 如果你是在write时限速就不一样了
其实我突然发现,都已经lock了,理论上是不需要Volatile.Read的
谢谢你的贡献