Skip to content

Commit

Permalink
ScriptLogger: Persistence
Browse files Browse the repository at this point in the history
~ Do not persist script hashes immediately, as this could cause a major influx of Vault writes.
  • Loading branch information
jf-06 committed Aug 30, 2024
1 parent 6275892 commit fd3190f
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 26 deletions.
8 changes: 8 additions & 0 deletions services/grid-bot/lib/settings/Providers/ScriptsSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ public string[] LoggedScriptHashes
);
set => Set(nameof(LoggedScriptHashes), value);
}

/// <summary>
/// Gets the interval to persist the logged script hashes.
/// </summary>
public TimeSpan LoggedScriptHashesPersistInterval => GetOrDefault(
nameof(LoggedScriptHashesPersistInterval),
TimeSpan.FromMinutes(5)
);
}
78 changes: 52 additions & 26 deletions services/grid-bot/lib/utility/Implementation/ScriptLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Grid.Bot.Utility;
using System.Net.Http;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Collections.Concurrent;

using Discord;
using Discord.Interactions;
Expand All @@ -20,31 +20,57 @@ namespace Grid.Bot.Utility;
/// Handles sending alerts to a Discord webhook.
/// </summary>
/// <seealso cref="IScriptLogger"/>
/// <remarks>
/// Creates a new instance of the <see cref="ScriptLogger"/> class.
/// </remarks>
/// <param name="localIpAddressProvider">The <see cref="ILocalIpAddressProvider"/> to use.</param>
/// <param name="percentageInvoker">The <see cref="IPercentageInvoker"/> to use.</param>
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/> to use.</param>
/// <param name="scriptsSettings">The <see cref="ScriptsSettings"/> to use.</param>
/// <exception cref="ArgumentNullException">
/// - <paramref name="localIpAddressProvider"/> cannot be null.
/// - <paramref name="percentageInvoker"/> cannot be null.
/// - <paramref name="httpClientFactory"/> cannot be null.
/// - <paramref name="scriptsSettings"/> cannot be null.
/// </exception>
/// <seealso cref="ScriptLogger"/>
public class ScriptLogger(
ILocalIpAddressProvider localIpAddressProvider,
IPercentageInvoker percentageInvoker,
IHttpClientFactory httpClientFactory,
ScriptsSettings scriptsSettings
) : IScriptLogger
public class ScriptLogger : IScriptLogger
{
private readonly ILocalIpAddressProvider _localIpAddressProvider = localIpAddressProvider ?? throw new ArgumentNullException(nameof(localIpAddressProvider));
private readonly IPercentageInvoker _percentageInvoker = percentageInvoker ?? throw new ArgumentNullException(nameof(percentageInvoker));
private readonly IHttpClientFactory _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
private readonly ScriptsSettings _scriptsSettings = scriptsSettings ?? throw new ArgumentNullException(nameof(scriptsSettings));
private readonly ILocalIpAddressProvider _localIpAddressProvider;
private readonly IPercentageInvoker _percentageInvoker;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ScriptsSettings _scriptsSettings;

private readonly ConcurrentBag<string> _scriptHashes = new();

/// <summary>
/// Creates a new instance of the <see cref="ScriptLogger"/> class.
/// </summary>
/// <param name="localIpAddressProvider">The <see cref="ILocalIpAddressProvider"/> to use.</param>
/// <param name="percentageInvoker">The <see cref="IPercentageInvoker"/> to use.</param>
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/> to use.</param>
/// <param name="scriptsSettings">The <see cref="ScriptsSettings"/> to use.</param>
/// <exception cref="ArgumentNullException">
/// - <paramref name="localIpAddressProvider"/> cannot be null.
/// - <paramref name="percentageInvoker"/> cannot be null.
/// - <paramref name="httpClientFactory"/> cannot be null.
/// - <paramref name="scriptsSettings"/> cannot be null.
/// </exception>
public ScriptLogger(
ILocalIpAddressProvider localIpAddressProvider,
IPercentageInvoker percentageInvoker,
IHttpClientFactory httpClientFactory,
ScriptsSettings scriptsSettings
)
{
_localIpAddressProvider = localIpAddressProvider ?? throw new ArgumentNullException(nameof(localIpAddressProvider));
_percentageInvoker = percentageInvoker ?? throw new ArgumentNullException(nameof(percentageInvoker));
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
_scriptsSettings = scriptsSettings ?? throw new ArgumentNullException(nameof(scriptsSettings));

foreach (var hash in _scriptsSettings.LoggedScriptHashes)
_scriptHashes.Add(hash);

Task.Factory.StartNew(PersistLoggedScriptHashes, TaskCreationOptions.LongRunning);
}

private void PersistLoggedScriptHashes()
{
while (true)
{
Task.Delay(_scriptsSettings.LoggedScriptHashesPersistInterval).Wait();

if (_scriptsSettings.LoggedScriptHashes.SequenceEqual(_scriptHashes)) continue;

_scriptsSettings.LoggedScriptHashes = [.. _scriptHashes];
}
}

/// <inheritdoc cref="IScriptLogger.LogScriptAsync(string, ShardedInteractionContext)"/>
public async Task LogScriptAsync(string script, ShardedInteractionContext context)
Expand Down Expand Up @@ -99,6 +125,6 @@ public async Task LogScriptAsync(string script, ShardedInteractionContext contex
await client.PostAsync(url, multipartContent);

// Add the hash to the list of logged hashes
_scriptsSettings.LoggedScriptHashes = [.. _scriptsSettings.LoggedScriptHashes, scriptHash];
_scriptHashes.Add(scriptHash);
}
}

0 comments on commit fd3190f

Please sign in to comment.