-
Notifications
You must be signed in to change notification settings - Fork 0
Pref : 비동기 작업 최적화 #22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,7 @@ public async Task<TokenResponse> GenerateTokensAsync(Guid userId) | |
| var accessTokenExpiresAt = DateTime.UtcNow.AddMinutes(15); | ||
| var refreshTokenExpiresAt = DateTime.UtcNow.AddMinutes(1440); | ||
|
|
||
|
Comment on lines
24
to
26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 토큰 만료 시간 하드코딩 → 설정화 권장 운영 정책 변경에 유연하게 대응할 수 있도록 IOptions 패턴으로 구성값화하세요. 예: TokenOptions { AccessTokenMinutes, RefreshTokenMinutes }를 DI로 주입. 🤖 Prompt for AI Agents |
||
| var stored = await _refreshTokenStorage.StoreRefreshTokenAsync(refreshToken, userId, refreshTokenExpiresAt).ConfigureAwait(false); | ||
| var stored = await _refreshTokenStorage.StoreRefreshTokenAsync(refreshToken, userId, refreshTokenExpiresAt); | ||
| if (!stored) | ||
| { | ||
| _logger.LogError("Failed to store refresh token for user {UserId}", userId); | ||
|
|
@@ -56,14 +56,14 @@ public async Task<TokenResponse> GenerateTokensAsync(Guid userId) | |
| return null; | ||
| } | ||
|
|
||
| var isValid = await _refreshTokenStorage.IsRefreshTokenValidAsync(refreshToken).ConfigureAwait(false); | ||
| var isValid = await _refreshTokenStorage.IsRefreshTokenValidAsync(refreshToken); | ||
| if (!isValid) | ||
| { | ||
| _logger.LogWarning("Refresh token not found in storage"); | ||
| return null; | ||
| } | ||
|
|
||
| var userId = await _refreshTokenStorage.GetUserIdFromRefreshTokenAsync(refreshToken).ConfigureAwait(false); | ||
| var userId = await _refreshTokenStorage.GetUserIdFromRefreshTokenAsync(refreshToken); | ||
| if (!userId.HasValue) | ||
| { | ||
| _logger.LogWarning("User ID not found for refresh token"); | ||
|
|
@@ -75,7 +75,7 @@ public async Task<TokenResponse> GenerateTokensAsync(Guid userId) | |
| var accessTokenExpiresAt = DateTime.UtcNow.AddMinutes(15); | ||
|
|
||
| // 기존 Refresh Token의 만료 시간 조회 | ||
| var refreshTokenExpiresAt = await _refreshTokenStorage.GetRefreshTokenExpiresAtAsync(refreshToken).ConfigureAwait(false); | ||
| var refreshTokenExpiresAt = await _refreshTokenStorage.GetRefreshTokenExpiresAtAsync(refreshToken); | ||
| if (!refreshTokenExpiresAt.HasValue) | ||
| { | ||
| _logger.LogWarning("Refresh token expiration time not found"); | ||
|
|
@@ -93,7 +93,7 @@ public async Task<TokenResponse> GenerateTokensAsync(Guid userId) | |
|
|
||
| public async Task<bool> RevokeRefreshTokenAsync(string refreshToken) | ||
| { | ||
| return await _refreshTokenStorage.RemoveRefreshTokenAsync(refreshToken).ConfigureAwait(false); | ||
| return await _refreshTokenStorage.RemoveRefreshTokenAsync(refreshToken); | ||
| } | ||
|
|
||
| public async Task<bool> ValidateRefreshTokenAsync(string refreshToken) | ||
|
|
@@ -110,7 +110,7 @@ public async Task<bool> ValidateRefreshTokenAsync(string refreshToken) | |
| return false; | ||
| } | ||
|
|
||
| return await _refreshTokenStorage.IsRefreshTokenValidAsync(refreshToken).ConfigureAwait(false); | ||
| return await _refreshTokenStorage.IsRefreshTokenValidAsync(refreshToken); | ||
| } | ||
|
|
||
| public Task<bool> ValidateAccessTokenAsync(string accessToken) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,37 +24,37 @@ public async Task<IEnumerable<User>> GetAllAsync() | |
| return await _context.Users | ||
| .Where(u => u.Status == AccountStatus.Active) | ||
| .OrderBy(u => u.Username) | ||
| .ToListAsync().ConfigureAwait(false); | ||
| .ToListAsync(); | ||
| } | ||
|
Comment on lines
24
to
28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 읽기 전용 쿼리에 AsNoTracking 적용으로 트래킹 오버헤드 제거 제안 레포 메서드 다수가 조회 전용입니다. EF Core 트래킹 비용 절감을 위해 AsNoTracking 추가를 권장합니다. Update/Delete는 내부에서 별도 조회로 트래킹 엔티티를 확보하므로 안전합니다. return await _context.Users
- .Where(u => u.Status == AccountStatus.Active)
+ .AsNoTracking()
+ .Where(u => u.Status == AccountStatus.Active)
.OrderBy(u => u.Username)
.ToListAsync();
-return await _context.Users.FirstOrDefaultAsync(u => u.Id == id && u.Status != AccountStatus.Deleted);
+return await _context.Users
+ .AsNoTracking()
+ .FirstOrDefaultAsync(u => u.Id == id && u.Status != AccountStatus.Deleted);
-return await _context.Users.FirstOrDefaultAsync(u => u.Username == username && u.Status != AccountStatus.Deleted);
+return await _context.Users
+ .AsNoTracking()
+ .FirstOrDefaultAsync(u => u.Username == username && u.Status != AccountStatus.Deleted);
-return await _context.Users.FirstOrDefaultAsync(u => u.Email == email && u.Status != AccountStatus.Deleted);
+return await _context.Users
+ .AsNoTracking()
+ .FirstOrDefaultAsync(u => u.Email == email && u.Status != AccountStatus.Deleted);
-return await _context.Users.FirstOrDefaultAsync(u => u.ProviderId == providerId && u.Status != AccountStatus.Deleted);
+return await _context.Users
+ .AsNoTracking()
+ .FirstOrDefaultAsync(u => u.ProviderId == providerId && u.Status != AccountStatus.Deleted);
-return await _context.Users.FirstOrDefaultAsync(u => u.Provider == provider && u.ProviderId == providerId && u.Status != AccountStatus.Deleted);
+return await _context.Users
+ .AsNoTracking()
+ .FirstOrDefaultAsync(u => u.Provider == provider && u.ProviderId == providerId && u.Status != AccountStatus.Deleted);
-return await _context.Users.FirstOrDefaultAsync(u => u.UID == uid && u.Status != AccountStatus.Deleted);
+return await _context.Users
+ .AsNoTracking()
+ .FirstOrDefaultAsync(u => u.UID == uid && u.Status != AccountStatus.Deleted);Also applies to: 32-33, 37-38, 42-43, 47-48, 52-53, 57-58 |
||
|
|
||
| public async Task<User?> GetByIdAsync(Guid id) | ||
| { | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Id == id && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Id == id && u.Status != AccountStatus.Deleted); | ||
| } | ||
|
|
||
| public async Task<User?> GetByUsernameAsync(string username) | ||
| { | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Username == username && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Username == username && u.Status != AccountStatus.Deleted); | ||
| } | ||
|
|
||
| public async Task<User?> GetByEmailAsync(string email) | ||
| { | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Email == email && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Email == email && u.Status != AccountStatus.Deleted); | ||
| } | ||
|
|
||
| public async Task<User?> GetByProviderIdAsync(string providerId) | ||
| { | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.ProviderId == providerId && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.ProviderId == providerId && u.Status != AccountStatus.Deleted); | ||
| } | ||
|
|
||
| public async Task<User?> GetByProviderAsync(string provider, string providerId) | ||
| { | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Provider == provider && u.ProviderId == providerId && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.Provider == provider && u.ProviderId == providerId && u.Status != AccountStatus.Deleted); | ||
| } | ||
|
|
||
| public async Task<User?> GetByUIDAsync(string uid) | ||
| { | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.UID == uid && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| return await _context.Users.FirstOrDefaultAsync(u => u.UID == uid && u.Status != AccountStatus.Deleted); | ||
| } | ||
|
|
||
| public async Task<User> CreateAsync(User user) | ||
|
|
@@ -65,14 +65,14 @@ public async Task<User> CreateAsync(User user) | |
| user.Status = AccountStatus.Active; | ||
|
|
||
| _context.Users.Add(user); | ||
| await _context.SaveChangesAsync().ConfigureAwait(false); | ||
| await _context.SaveChangesAsync(); | ||
|
|
||
| return user; | ||
| } | ||
|
|
||
| public async Task<User> UpdateAsync(User user) | ||
| { | ||
| var existingUser = await _context.Users.FirstOrDefaultAsync(u => u.Id == user.Id && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| var existingUser = await _context.Users.FirstOrDefaultAsync(u => u.Id == user.Id && u.Status != AccountStatus.Deleted); | ||
| if (existingUser == null) { | ||
| throw new NotFoundException(ErrorCode.USER_NOT_FOUND, "User", user.Id); | ||
| } | ||
|
|
@@ -85,22 +85,22 @@ public async Task<User> UpdateAsync(User user) | |
| existingUser.Status = user.Status; | ||
| existingUser.Update(); | ||
|
|
||
| await _context.SaveChangesAsync().ConfigureAwait(false); | ||
| await _context.SaveChangesAsync(); | ||
|
|
||
| return existingUser; | ||
| } | ||
|
|
||
| public async Task DeleteAsync(Guid id) | ||
| { | ||
| var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == id && u.Status != AccountStatus.Deleted).ConfigureAwait(false); | ||
| var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == id && u.Status != AccountStatus.Deleted); | ||
|
|
||
| if (user == null) { | ||
| throw new NotFoundException(ErrorCode.USER_NOT_FOUND, "User", id); | ||
| } | ||
|
|
||
| user.Status = AccountStatus.Deleted; | ||
| user.Update(); | ||
| await _context.SaveChangesAsync().ConfigureAwait(false); | ||
| await _context.SaveChangesAsync(); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
CloseAsync에 무제한 CancellationToken.None 사용 지양
네트워크 이슈 시 무기한 블로킹될 수 있습니다. 짧은 타임아웃을 가진 CTS를 사용하세요.
📝 Committable suggestion
🤖 Prompt for AI Agents