C
C#6mo ago
Kiel

✅ Creating a collection similar to Channel/Queue that does not "remove" elements from the collection

I have a service in my bot which stores audit logs from Discord as they are relayed across the gateway. I want to store these in memory so that they can be accessed at any point, but I also want to preserve the audit logs as they come in (via a method that waits for an audit log meeting criteria). What are some options available to me? I don't think I can use Channel or (Concurrent)Queue because they both "remove" elements from themselves as I consume them...unless there's a way to not do that?
private readonly ConcurrentDictionary<Snowflake, ConcurrentDictionary<Snowflake, IAuditLog>> _auditLogs = new();

public ConcurrentDictionary<Snowflake, IAuditLog> GetAllAuditLogs(Snowflake guildId)
=> _auditLogs.GetOrAdd(guildId, _ => new ConcurrentDictionary<Snowflake, IAuditLog>());

protected override ValueTask OnAuditLogCreated(AuditLogCreatedEventArgs e)
{
var dict = _auditLogs.GetOrAdd(e.GuildId, _ => new ConcurrentDictionary<Snowflake, IAuditLog>());
dict[e.AuditLog.Id] = e.AuditLog;
return ValueTask.CompletedTask;
}

public async Task<TAuditLog?> WaitForAuditLogAsync<TAuditLog>(Snowflake guildId, Func<TAuditLog, bool> func, TimeSpan? timeout = null)
where TAuditLog : class, IAuditLog
{
// I want to wait until OnAuditLogCreated produces an audit log matching `func`, or until timeout
}
private readonly ConcurrentDictionary<Snowflake, ConcurrentDictionary<Snowflake, IAuditLog>> _auditLogs = new();

public ConcurrentDictionary<Snowflake, IAuditLog> GetAllAuditLogs(Snowflake guildId)
=> _auditLogs.GetOrAdd(guildId, _ => new ConcurrentDictionary<Snowflake, IAuditLog>());

protected override ValueTask OnAuditLogCreated(AuditLogCreatedEventArgs e)
{
var dict = _auditLogs.GetOrAdd(e.GuildId, _ => new ConcurrentDictionary<Snowflake, IAuditLog>());
dict[e.AuditLog.Id] = e.AuditLog;
return ValueTask.CompletedTask;
}

public async Task<TAuditLog?> WaitForAuditLogAsync<TAuditLog>(Snowflake guildId, Func<TAuditLog, bool> func, TimeSpan? timeout = null)
where TAuditLog : class, IAuditLog
{
// I want to wait until OnAuditLogCreated produces an audit log matching `func`, or until timeout
}
1 Reply
FestivalDelGelato
Queue, for example, has both Peek and is enumerable so you can look at the elements inside without consuming them

Did you find this page helpful?