Skip to content

Commit

Permalink
Further decrease server load
Browse files Browse the repository at this point in the history
We can keep inventory checksum before deduplication in the cache. If it's determined to be the same, then our inventory state didn't change, so it also doesn't make much sense to ask server for set parts and announcement.
  • Loading branch information
JustArchi authored and pull[bot] committed May 14, 2024
1 parent 1b8b69e commit ead00ab
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 6 deletions.
19 changes: 19 additions & 0 deletions ArchiSteamFarm.OfficialPlugins.ItemsMatcher/BotCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,25 @@ internal string? LastAnnouncedTradeToken {
}
}

internal string? LastInventoryChecksumBeforeDeduplication {
get => BackingLastInventoryChecksumBeforeDeduplication;

set {
if (BackingLastInventoryChecksumBeforeDeduplication == value) {
return;
}

BackingLastInventoryChecksumBeforeDeduplication = value;
Utilities.InBackground(Save);
}
}

[JsonProperty]
private string? BackingLastAnnouncedTradeToken;

[JsonProperty]
private string? BackingLastInventoryChecksumBeforeDeduplication;

private BotCache(string filePath) : this() {
ArgumentException.ThrowIfNullOrEmpty(filePath);

Expand All @@ -65,6 +81,9 @@ private BotCache(string filePath) : this() {
[UsedImplicitly]
public bool ShouldSerializeBackingLastAnnouncedTradeToken() => !string.IsNullOrEmpty(BackingLastAnnouncedTradeToken);

[UsedImplicitly]
public bool ShouldSerializeBackingLastInventoryChecksumBeforeDeduplication() => !string.IsNullOrEmpty(BackingLastInventoryChecksumBeforeDeduplication);

[UsedImplicitly]
public bool ShouldSerializeLastAnnouncedAssetsForListing() => LastAnnouncedAssetsForListing.Count > 0;

Expand Down
45 changes: 39 additions & 6 deletions ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,27 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =
}
}

BotCache ??= await BotCache.CreateOrLoad(BotCacheFilePath).ConfigureAwait(false);

string inventoryChecksumBeforeDeduplication = Backend.GenerateChecksumFor(assetsForListing);

if ((tradeToken == BotCache.LastAnnouncedTradeToken) && !string.IsNullOrEmpty(BotCache.LastInventoryChecksumBeforeDeduplication)) {
if (inventoryChecksumBeforeDeduplication == BotCache.LastInventoryChecksumBeforeDeduplication) {
// We've determined our state to be the same, we can skip announce entirely and start sending heartbeats exclusively
bool triggerImmediately = !ShouldSendHeartBeats;

LastAnnouncement = DateTime.UtcNow;
ShouldSendAnnouncementEarlier = false;
ShouldSendHeartBeats = true;

if (triggerImmediately) {
Utilities.InBackground(() => OnHeartBeatTimer());
}

return;
}
}

if (!SignedInWithSteam) {
HttpStatusCode? signInWithSteam = await ArchiNet.SignInWithSteam(Bot, WebBrowser).ConfigureAwait(false);

Expand All @@ -350,8 +371,6 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =
SignedInWithSteam = true;
}

BotCache ??= await BotCache.CreateOrLoad(BotCacheFilePath).ConfigureAwait(false);

if (!matchEverything) {
// We should deduplicate our sets before sending them to the server, for doing that we'll use ASFB set parts data
HashSet<uint> realAppIDs = new();
Expand Down Expand Up @@ -444,6 +463,9 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =
LastAnnouncement = DateTime.UtcNow;
ShouldSendAnnouncementEarlier = ShouldSendHeartBeats = false;

// There is a possibility that our inventory has changed even if our announced assets did not, record that
BotCache.LastInventoryChecksumBeforeDeduplication = inventoryChecksumBeforeDeduplication;

return;
}
}
Expand All @@ -453,6 +475,9 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =
LastAnnouncement = DateTime.UtcNow;
ShouldSendAnnouncementEarlier = ShouldSendHeartBeats = false;

// There is a possibility that our inventory has changed even if our announced assets did not, record that
BotCache.LastInventoryChecksumBeforeDeduplication = inventoryChecksumBeforeDeduplication;

Bot.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(assetsForListing)} > {MaxItemsCount}"));

return;
Expand All @@ -463,11 +488,18 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =

if ((tradeToken == BotCache.LastAnnouncedTradeToken) && (checksum == previousChecksum)) {
// We've determined our state to be the same, we can skip announce entirely and start sending heartbeats exclusively
bool triggerImmediately = !ShouldSendHeartBeats;

LastAnnouncement = DateTime.UtcNow;
ShouldSendAnnouncementEarlier = false;
ShouldSendHeartBeats = true;

Utilities.InBackground(() => OnHeartBeatTimer());
if (triggerImmediately) {
Utilities.InBackground(() => OnHeartBeatTimer());
}

// There is a possibility that our inventory has changed even if our announced assets did not, record that
BotCache.LastInventoryChecksumBeforeDeduplication = inventoryChecksumBeforeDeduplication;

return;
}
Expand All @@ -481,7 +513,7 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =

BasicResponse? diffResponse = await Backend.AnnounceDiffForListing(WebBrowser, Bot.SteamID, inventoryAddedChanged, checksum, acceptedMatchableTypes, (uint) inventory.Count, matchEverything, tradeToken, previousInventoryState.Values, previousChecksum, nickname, avatarHash).ConfigureAwait(false);

if (HandleAnnounceResponse(BotCache, tradeToken, previousChecksum, assetsForListing, diffResponse)) {
if (HandleAnnounceResponse(BotCache, tradeToken, inventoryChecksumBeforeDeduplication, assetsForListing, previousChecksum, diffResponse)) {
// Our diff announce has succeeded, we have nothing to do further
Bot.ArchiLogger.LogGenericInfo(Strings.Success);

Expand All @@ -493,7 +525,7 @@ internal async Task OnPersonaState(string? nickname = null, string? avatarHash =

BasicResponse? response = await Backend.AnnounceForListing(WebBrowser, Bot.SteamID, assetsForListing, checksum, acceptedMatchableTypes, (uint) inventory.Count, matchEverything, tradeToken, nickname, avatarHash).ConfigureAwait(false);

HandleAnnounceResponse(BotCache, tradeToken, assetsForListing: assetsForListing, response: response);
HandleAnnounceResponse(BotCache, tradeToken, inventoryChecksumBeforeDeduplication, assetsForListing, response: response);
} finally {
RequestsSemaphore.Release();
}
Expand All @@ -512,7 +544,7 @@ internal void TriggerMatchActivelyEarlier() {
}
}

private bool HandleAnnounceResponse(BotCache botCache, string tradeToken, string? previousInventoryChecksum = null, ICollection<AssetForListing>? assetsForListing = null, BasicResponse? response = null) {
private bool HandleAnnounceResponse(BotCache botCache, string tradeToken, string? inventoryChecksumBeforeDeduplication = null, ICollection<AssetForListing>? assetsForListing = null, string? previousInventoryChecksum = null, BasicResponse? response = null) {
ArgumentNullException.ThrowIfNull(botCache);
ArgumentException.ThrowIfNullOrEmpty(tradeToken);

Expand Down Expand Up @@ -577,6 +609,7 @@ private bool HandleAnnounceResponse(BotCache botCache, string tradeToken, string

botCache.LastAnnouncedAssetsForListing.ReplaceWith(assetsForListing);
botCache.LastAnnouncedTradeToken = tradeToken;
botCache.LastInventoryChecksumBeforeDeduplication = inventoryChecksumBeforeDeduplication;
}

return true;
Expand Down

0 comments on commit ead00ab

Please sign in to comment.