Fix perf with cache
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Domain.Accounts;
|
||||
using Managing.Domain.Users;
|
||||
using Managing.Infrastructure.Databases.PostgreSql.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -66,12 +67,12 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
||||
}, nameof(GetUserByAgentNameAsync), ("agentName", agentName));
|
||||
}
|
||||
|
||||
public async Task<User> GetUserByNameAsync(string name)
|
||||
public async Task<User> GetUserByNameAsync(string name, bool fetchAccounts = false)
|
||||
{
|
||||
return await ExecuteWithLoggingAsync(async () =>
|
||||
{
|
||||
// Check cache first for frequently accessed users
|
||||
var cacheKey = $"user_name_{name}";
|
||||
var cacheKey = fetchAccounts ? $"user_name_with_accounts_{name}" : $"user_name_{name}";
|
||||
var cachedUser = _cacheService.GetValue<User>(cacheKey);
|
||||
if (cachedUser != null)
|
||||
{
|
||||
@@ -82,28 +83,61 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
||||
{
|
||||
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
|
||||
|
||||
// Optimized query with explicit SELECT to avoid loading unnecessary data
|
||||
var userEntity = await _context.Users
|
||||
.AsNoTracking()
|
||||
.Where(u => u.Name == name)
|
||||
.Select(u => new UserEntity
|
||||
User user;
|
||||
|
||||
if (fetchAccounts)
|
||||
{
|
||||
// Fetch user with accounts in a single query
|
||||
var userEntity = await _context.Users
|
||||
.AsNoTracking()
|
||||
.Include(u => u.Accounts)
|
||||
.Where(u => u.Name == name)
|
||||
.FirstOrDefaultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (userEntity == null)
|
||||
throw new InvalidOperationException($"User with name '{name}' not found");
|
||||
|
||||
user = PostgreSqlMappers.Map(userEntity);
|
||||
|
||||
// Map accounts using the existing mapper
|
||||
if (userEntity.Accounts != null)
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.Name,
|
||||
AgentName = u.AgentName,
|
||||
AvatarUrl = u.AvatarUrl,
|
||||
TelegramChannel = u.TelegramChannel
|
||||
})
|
||||
.FirstOrDefaultAsync()
|
||||
.ConfigureAwait(false);
|
||||
user.Accounts = userEntity.Accounts.Select(PostgreSqlMappers.Map).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
user.Accounts = new List<Account>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Optimized query with explicit SELECT to avoid loading unnecessary data
|
||||
var userEntity = await _context.Users
|
||||
.AsNoTracking()
|
||||
.Where(u => u.Name == name)
|
||||
.Select(u => new UserEntity
|
||||
{
|
||||
Id = u.Id,
|
||||
Name = u.Name,
|
||||
AgentName = u.AgentName,
|
||||
AvatarUrl = u.AvatarUrl,
|
||||
TelegramChannel = u.TelegramChannel
|
||||
})
|
||||
.FirstOrDefaultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (userEntity == null)
|
||||
throw new InvalidOperationException($"User with name '{name}' not found");
|
||||
if (userEntity == null)
|
||||
throw new InvalidOperationException($"User with name '{name}' not found");
|
||||
|
||||
var user = PostgreSqlMappers.Map(userEntity);
|
||||
user = PostgreSqlMappers.Map(userEntity);
|
||||
user.Accounts = new List<Account>(); // Initialize empty list
|
||||
}
|
||||
|
||||
// Cache user for 5 minutes since user data doesn't change frequently
|
||||
_cacheService.SaveValue(cacheKey, user, TimeSpan.FromMinutes(5));
|
||||
// Use shorter cache time when including accounts since accounts change more frequently
|
||||
var cacheTime = fetchAccounts ? TimeSpan.FromMinutes(2) : TimeSpan.FromMinutes(5);
|
||||
_cacheService.SaveValue(cacheKey, user, cacheTime);
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -111,7 +145,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
||||
{
|
||||
await PostgreSqlConnectionHelper.SafeCloseConnectionAsync(_context);
|
||||
}
|
||||
}, nameof(GetUserByNameAsync), ("name", name));
|
||||
}, nameof(GetUserByNameAsync), ("name", name), ("fetchAccounts", fetchAccounts));
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<User>> GetAllUsersAsync()
|
||||
@@ -214,7 +248,9 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
|
||||
|
||||
// Invalidate cache for updated user - handle both old and new AgentName
|
||||
var nameCacheKey = $"user_name_{user.Name}";
|
||||
var nameWithAccountsCacheKey = $"user_name_with_accounts_{user.Name}";
|
||||
_cacheService.RemoveValue(nameCacheKey);
|
||||
_cacheService.RemoveValue(nameWithAccountsCacheKey);
|
||||
|
||||
// Invalidate old AgentName cache if it existed
|
||||
if (!string.IsNullOrEmpty(oldAgentName))
|
||||
|
||||
Reference in New Issue
Block a user