Middle+
Implementieren Sie eine Methode, die den vollständigen Namen des Benutzers aus dem Speicher (IDbRepository oder ICacheRepository) ausfüllt und das angereicherte Ereignis weitergibt (IEventSaver) Es ist notwendig, maximale Leistung zu erzielen Der Cache enthält 99,9 % der aktuellen Daten Die ursprüngliche Reihenfolge der Ereignisse beim Speichern kann verletzt werden public async Task Enrich(IEnumerable<UserEvent> events) { }
sobes.tech KI
Antwort von 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);
}
Такой подход минимизирует обращения к базе, использует кеш максимально эффективно и позволяет параллельно сохранять обогащённые события.