feat: remote await events from gateway

This commit is contained in:
alyssa 2025-03-29 17:55:01 +00:00
parent 64ff69723c
commit 15c992c572
17 changed files with 439 additions and 30 deletions

View file

@ -1,7 +1,10 @@
using Serilog;
using System.Net;
using System.Text;
using System.Text.Json;
using NodaTime;
using Myriad.Serialization;
using Myriad.Types;
@ -12,6 +15,7 @@ public class HttpDiscordCache: IDiscordCache
private readonly ILogger _logger;
private readonly HttpClient _client;
private readonly Uri _cacheEndpoint;
private readonly string? _eventTarget;
private readonly int _shardCount;
private readonly ulong _ownUserId;
@ -21,11 +25,12 @@ public class HttpDiscordCache: IDiscordCache
public EventHandler<(bool?, string)> OnDebug;
public HttpDiscordCache(ILogger logger, HttpClient client, string cacheEndpoint, int shardCount, ulong ownUserId, bool useInnerCache)
public HttpDiscordCache(ILogger logger, HttpClient client, string cacheEndpoint, string? eventTarget, int shardCount, ulong ownUserId, bool useInnerCache)
{
_logger = logger;
_client = client;
_cacheEndpoint = new Uri(cacheEndpoint);
_eventTarget = eventTarget;
_shardCount = shardCount;
_ownUserId = ownUserId;
_jsonSerializerOptions = new JsonSerializerOptions().ConfigureForMyriad();
@ -65,6 +70,68 @@ public class HttpDiscordCache: IDiscordCache
return JsonSerializer.Deserialize<T>(plaintext, _jsonSerializerOptions);
}
private Task AwaitEvent(ulong guildId, object data)
=> AwaitEventShard((int)((guildId >> 22) % (ulong)_shardCount), data);
private async Task AwaitEventShard(int shardId, object data)
{
if (_eventTarget == null)
throw new Exception("missing event target for remote await event");
var cluster = _cacheEndpoint.Authority;
// todo: there should not be infra-specific code here
if (cluster.Contains(".service.consul") || cluster.Contains("process.pluralkit-gateway.internal"))
// int(((guild_id >> 22) % shard_count) / 16)
cluster = $"cluster{shardId / 16}.{cluster}";
var response = await _client.PostAsync(
$"{_cacheEndpoint.Scheme}://{cluster}/await_event",
new StringContent(JsonSerializer.Serialize(data), Encoding.UTF8)
);
if (response.StatusCode != HttpStatusCode.NoContent)
throw new Exception($"failed to await event from gateway: {response.StatusCode}");
}
public async Task AwaitReaction(ulong guildId, ulong messageId, ulong userId, Duration? timeout)
{
var obj = new
{
message_id = messageId,
user_id = userId,
target = _eventTarget!,
timeout = timeout?.TotalSeconds,
};
await AwaitEvent(guildId, obj);
}
public async Task AwaitMessage(ulong guildId, ulong channelId, ulong authorId, Duration? timeout, string[] options = null)
{
var obj = new
{
channel_id = channelId,
author_id = authorId,
target = _eventTarget!,
timeout = timeout?.TotalSeconds,
options = options,
};
await AwaitEvent(guildId, obj);
}
public async Task AwaitInteraction(int shardId, string id, Duration? timeout)
{
var obj = new
{
id = id,
target = _eventTarget!,
timeout = timeout?.TotalSeconds,
};
await AwaitEventShard(shardId, obj);
}
public async Task<Guild?> TryGetGuild(ulong guildId)
{
var hres = await QueryCache<Guild?>($"/guilds/{guildId}", guildId);

View file

@ -21,6 +21,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NodaTime" Version="3.2.0" />
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.1.0" />
<PackageReference Include="Polly" Version="8.5.0" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageReference Include="Serilog" Version="4.2.0" />

View file

@ -2,6 +2,22 @@
"version": 1,
"dependencies": {
"net8.0": {
"NodaTime": {
"type": "Direct",
"requested": "[3.2.0, )",
"resolved": "3.2.0",
"contentHash": "yoRA3jEJn8NM0/rQm78zuDNPA3DonNSZdsorMUj+dltc1D+/Lc5h9YXGqbEEZozMGr37lAoYkcSM/KjTVqD0ow=="
},
"NodaTime.Serialization.JsonNet": {
"type": "Direct",
"requested": "[3.1.0, )",
"resolved": "3.1.0",
"contentHash": "eEr9lXUz50TYr4rpeJG4TDAABkpxjIKr5mDSi/Zav8d6Njy6fH7x4ZtNwWFj0Vd+vIvEZNrHFQ4Gfy8j4BqRGg==",
"dependencies": {
"Newtonsoft.Json": "13.0.3",
"NodaTime": "[3.0.0, 4.0.0)"
}
},
"Polly": {
"type": "Direct",
"requested": "[8.5.0, )",
@ -52,6 +68,11 @@
"resolved": "6.0.0",
"contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA=="
},
"Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"Pipelines.Sockets.Unofficial": {
"type": "Transitive",
"resolved": "2.2.8",