Port ArchiBot's WebBrowser client errors handling

First important change is for all requests sent by ASF. Across those 4 years of development I do not remember a single situation where retrying on 4xx status code brought any improvement, bad request has to be handled by us, access denied and not found won't disappear after retry, all other ones are rather unused. Therefore, it makes sense to skip remaining tries on 4xx errors and do not flood the service with requests that are very unlikely to change anything.
Second change is smaller one and it allows the consumer of WebBrowser to declare that he's interested in handling client error codes himself. This way he can add extra logic and appropriately react to them - ASF uses it in statistics module, where the listing can signal refusal to list due to e.g. outdated ASF version through 403. Previously this was treated on the same level as timeout, which wasn't optimal.
This commit is contained in:
JustArchi
2019-04-05 16:24:02 +02:00
parent 2c68e9f70e
commit 91e495605b
3 changed files with 193 additions and 62 deletions

View File

@@ -33,7 +33,6 @@ using Newtonsoft.Json;
namespace ArchiSteamFarm {
internal sealed class Statistics : IDisposable {
private const byte MaxHeartBeatTTL = MinHeartBeatTTL + WebBrowser.MaxTries; // Maximum amount of minutes until we give up on sending further HeartBeats
private const byte MaxMatchedBotsHard = 40;
private const byte MaxMatchedBotsSoft = 20;
private const byte MaxMatchingRounds = 10;
@@ -102,12 +101,15 @@ namespace ArchiSteamFarm {
{ "SteamID", Bot.SteamID.ToString() }
};
// Listing is free to deny our announce request, hence we don't retry
if (await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, maxTries: 1).ConfigureAwait(false) == null) {
if (DateTime.UtcNow > LastHeartBeat.AddMinutes(MaxHeartBeatTTL)) {
ShouldSendHeartBeats = false;
Bot.RequestPersonaStateUpdate();
}
WebBrowser.BasicResponse response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
if (response == null) {
return;
}
if (response.StatusCode.IsClientErrorCode()) {
LastHeartBeat = DateTime.MinValue;
ShouldSendHeartBeats = false;
return;
}
@@ -200,11 +202,19 @@ namespace ArchiSteamFarm {
{ "TradeToken", tradeToken }
};
// Listing is free to deny our announce request, hence we don't retry
bool announced = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, maxTries: 1).ConfigureAwait(false) != null;
WebBrowser.BasicResponse response = await Bot.ArchiWebHandler.WebBrowser.UrlPost(request, data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors).ConfigureAwait(false);
LastHeartBeat = announced ? DateTime.UtcNow : DateTime.MinValue;
ShouldSendHeartBeats = announced;
if (response == null) {
return;
}
if (response.StatusCode.IsClientErrorCode()) {
LastHeartBeat = DateTime.MinValue;
ShouldSendHeartBeats = false;
}
LastHeartBeat = DateTime.UtcNow;
ShouldSendHeartBeats = true;
} finally {
RequestsSemaphore.Release();
}