Skip to content

Instantly share code, notes, and snippets.

@BashkaMen
Created July 21, 2025 13:06
Show Gist options
  • Save BashkaMen/9617ba26760c043f34448523a167d53b to your computer and use it in GitHub Desktop.
Save BashkaMen/9617ba26760c043f34448523a167d53b to your computer and use it in GitHub Desktop.
public abstract class AbstractActor<TMsg> : BackgroundService
{
private readonly Channel<TMsg> _mailbox;
public AbstractActor()
{
_mailbox = Channel.CreateUnbounded<TMsg>();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (true)
{
//_mailbox.Reader.Count - можем записывать в метрику длину очереди
var msg = await _mailbox.Reader.ReadAsync(stoppingToken);
try
{
await HandleAsync(msg, stoppingToken);
// можем инкрементить и считать rps обработки
}
catch (Exception e)
{
await HandleErrorAsync(e, msg, stoppingToken);
}
}
}
public async Task SendAsync(TMsg msg)
{
// тут запишем скорость вставки в очередь - будем видеть когда бомбят
await _mailbox.Writer.WriteAsync(msg);
}
protected abstract Task HandleAsync(TMsg msg, CancellationToken ct);
protected abstract Task HandleErrorAsync(Exception error, TMsg message, CancellationToken ct);
}
// можно поставить библиотеку union для автогенерации Match функции
[Union]
public abstract record SubscriptionManagerMsg
{
public record Subscribe(string Ticker) : SubscriptionManagerMsg;
public record Unsubscribe(string Ticker) : SubscriptionManagerMsg;
}
public interface ISubscriptionManager
{
Task Subscribe(string ticker);
Task Unsubscribe(string ticker);
}
// можно закрыть интерфейсом
public class SubscriptionManager : AbstractActor<SubscriptionManagerMsg>, ISubscriptionManager
{
public SubscriptionManager()
{
// di работает
}
protected override async Task HandleAsync(SubscriptionManagerMsg msg, CancellationToken ct)
{
await msg.Match(
sub => Console.WriteLine($"Subscribed to {sub.Ticker}"),
unsub => Console.WriteLine($"Unsubscribed from {unsub.Ticker}"),
);
_pubsub.SendAsync(...);
}
protected override async Task HandleErrorAsync(
Exception error,
SubscriptionManagerMsg message,
CancellationToken ct)
{
logger.LogError(error);
}
public async Task Subscribe(string ticker)
{
await SendAsync(new SubscriptionManagerMsg.Subscribe(ticker));
}
public async Task Unsubscribe(string ticker)
{
await SendAsync(new SubscriptionManagerMsg.Unsubscribe(ticker));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment