Middle+
Implementeer een methode die de volledige naam van de gebruiker vult uit de opslag (IDbRepository of ICacheRepository) en het verrijkte evenement verder stuurt (IEventSaver) Het is noodzakelijk om maximale prestaties te bereiken In de cache bevinden zich 99,9% van de actuele gegevens De oorspronkelijke volgorde van gebeurtenissen bij het opslaan kan worden geschonden public async Task Enrich(IEnumerable<UserEvent> events) { }
sobes.tech AI
Antwoord van AI
Для максимальной производительности при обогащении событий именами пользователей из кеша и базы можно:
- Сначала попытаться получить данные из кеша (ICacheRepository) для всех пользователей.
- Для тех, кого нет в кеше (0.1%), сделать пакетный запрос в базу (IDbRepository).
- Обновить кеш новыми данными, если нужно.
- Обогатить события полным именем.
- Поскольку порядок можно нарушать, можно обрабатывать события параллельно.
Пример реализации:
public async Task Enrich(IEnumerable<UserEvent> events)
{
var eventList = events.ToList();
var userIds = eventList.Select(e => e.UserId).Distinct().ToList();
// Пытаемся получить из кеша
var cachedUsers = await cacheRepository.GetUsersAsync(userIds);
var missingUserIds = userIds.Except(cachedUsers.Select(u => u.Id)).ToList();
// Запрашиваем недостающих из базы
var dbUsers = missingUserIds.Any() ? await dbRepository.GetUsersAsync(missingUserIds) : new List<User>();
// Обновляем кеш
if (dbUsers.Any())
{
await cacheRepository.SetUsersAsync(dbUsers);
}
// Объединяем данные
var allUsers = cachedUsers.Concat(dbUsers).ToDictionary(u => u.Id);
// Обогащаем события и сохраняем
var tasks = eventList.Select(async e =>
{
if (allUsers.TryGetValue(e.UserId, out var user))
{
e.FullName = user.FullName;
}
await eventSaver.SaveAsync(e);
});
await Task.WhenAll(tasks);
}
Такой подход минимизирует обращения к базе, использует кеш максимально эффективно и позволяет параллельно сохранять обогащённые события.