C
C#4mo 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
Omnissiah
Omnissiah4mo ago
Queue, for example, has both Peek and is enumerable so you can look at the elements inside without consuming them
Want results from more Discord servers?
Add your server