首次加载URL时增加重试机制 (#413)

#355
This commit is contained in:
nilaoda 2024-06-30 20:27:54 +08:00 committed by GitHub
parent 606db68dbb
commit 04cf234974
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 25 deletions

3
.gitignore vendored
View File

@ -40,6 +40,9 @@ bld/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Rider
.idea
# Visual Studio 2017 auto generated files
Generated\ Files/

View File

@ -0,0 +1,38 @@
using System.Net;
using N_m3u8DL_RE.Common.Log;
using Spectre.Console;
namespace N_m3u8DL_RE.Common.Util;
public class RetryUtil
{
public static async Task<T?> WebRequestRetryAsync<T>(Func<Task<T>> funcAsync, int maxRetries = 10, int retryDelayMilliseconds = 1500, int retryDelayIncrementMilliseconds = 0)
{
var retryCount = 0;
var result = default(T);
Exception currentException = new();
while (retryCount < maxRetries)
{
try
{
result = await funcAsync();
break;
}
catch (Exception ex) when (ex is WebException or IOException or HttpRequestException)
{
currentException = ex;
retryCount++;
Logger.WarnMarkUp($"[grey]{ex.Message.EscapeMarkup()} ({retryCount}/{maxRetries})[/]");
await Task.Delay(retryDelayMilliseconds + (retryDelayIncrementMilliseconds * (retryCount - 1)));
}
}
if (retryCount == maxRetries)
{
throw new Exception($"Failed to execute action after {maxRetries} retries.", currentException);
}
return result;
}
}

View File

@ -30,25 +30,25 @@ namespace N_m3u8DL_RE.Parser
this.parserConfig = parserConfig;
}
public void LoadSourceFromUrl(string url)
public async Task LoadSourceFromUrlAsync(string url)
{
Logger.Info(ResString.loadingUrl + url);
if (url.StartsWith("file:"))
{
var uri = new Uri(url);
this.rawText = File.ReadAllText(uri.LocalPath);
this.rawText = await File.ReadAllTextAsync(uri.LocalPath);
parserConfig.OriginalUrl = parserConfig.Url = url;
}
else if (url.StartsWith("http"))
{
parserConfig.OriginalUrl = url;
(this.rawText, url) = HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers).Result;
(this.rawText, url) = await HTTPUtil.GetWebSourceAndNewUrlAsync(url, parserConfig.Headers);
parserConfig.Url = url;
}
else if (File.Exists(url))
{
url = Path.GetFullPath(url);
this.rawText = File.ReadAllText(url);
this.rawText = await File.ReadAllTextAsync(url);
parserConfig.OriginalUrl = parserConfig.Url = new Uri(url).AbsoluteUri;
}
this.rawText = rawText.Trim();
@ -134,22 +134,11 @@ namespace N_m3u8DL_RE.Parser
try
{
await semaphore.WaitAsync();
int retryCount = 5; //增加重试
reGet:
try
await RetryUtil.WebRequestRetryAsync(async () =>
{
await extractor.RefreshPlayListAsync(streamSpecs);
}
catch (Exception ex)
{
if (retryCount-- > 0)
{
Logger.WarnMarkUp($"[grey]Refresh Exception: {ex.Message.EscapeMarkup()} retryCount: {retryCount}[/]");
await Task.Delay(1000);
goto reGet;
}
else throw;
}
return true;
}, retryDelayMilliseconds: 1000, maxRetries: 5);
}
finally
{

View File

@ -62,11 +62,9 @@ namespace N_m3u8DL_RE
static int GetOrder(StreamSpec streamSpec)
{
if (streamSpec.Channels == null) return 0;
else
{
var str = streamSpec.Channels.Split('/')[0];
return int.TryParse(str, out var order) ? order : 0;
}
var str = streamSpec.Channels.Split('/')[0];
return int.TryParse(str, out var order) ? order : 0;
}
static async Task DoWorkAsync(MyOption option)
@ -208,8 +206,12 @@ namespace N_m3u8DL_RE
//流提取器配置
var extractor = new StreamExtractor(parserConfig);
extractor.LoadSourceFromUrl(url);
// 从链接加载内容
await RetryUtil.WebRequestRetryAsync(async () =>
{
await extractor.LoadSourceFromUrlAsync(url);
return true;
});
//解析流信息
var streams = await extractor.ExtractStreamsAsync();