docs: fastSession 오류 수정 내용 문서화
This commit is contained in:
153
fastSession-Error-correction.md
Normal file
153
fastSession-Error-correction.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# fastSession 오류 수정 문서
|
||||
|
||||
## 개요
|
||||
프론트엔드 fastSession 모달에서 시작 버튼을 누르면 `localhost:5000`에서 오류가 발생했습니다.
|
||||
|
||||
**오류 메시지:**
|
||||
```
|
||||
An error occured while saving the entity changes. See the inner exception for details
|
||||
```
|
||||
|
||||
## 문제 분석
|
||||
|
||||
### 1. 오류 발생 경로
|
||||
1. 프론트엔드 (`app.js:2102`) - `fastStart()` 함수 호출
|
||||
2. API 요청: `POST /api/fast/start`
|
||||
3. 컨트롤러 (`ExperionControllers.cs:672`) - `ExperionFastController.Start()`
|
||||
4. 서비스 (`ExperionFastService.cs:68`) - `StartSessionAsync()`
|
||||
5. DB 서비스 (`ExperionDbContext.cs:732`) - `CreateFastSessionAsync()`
|
||||
6. DB 업데이트 (`ExperionDbContext.cs:751`) - `UpdateFastSessionStatusAsync()`
|
||||
|
||||
### 2. 근본 원인
|
||||
|
||||
`CreateFastSessionAsync` 메서드에서 `Status`를 `"Pending"`으로 설정하고, 이후 `UpdateFastSessionStatusAsync`를 호출하여 `"Running"`으로 변경하면서 EF Core의 변경 감지가 충돌을 일으켰습니다.
|
||||
|
||||
**기존 코드 흐름:**
|
||||
```csharp
|
||||
// CreateFastSessionAsync - Status: "Pending"
|
||||
var session = new FastSession
|
||||
{
|
||||
Status = "Pending", // ← Pending으로 설정
|
||||
// ...
|
||||
};
|
||||
_ctx.FastSessions.Add(session);
|
||||
await _ctx.SaveChangesAsync(); // ← 첫 번째 SaveChanges
|
||||
|
||||
// 이후 StartSessionAsync에서
|
||||
await db.UpdateFastSessionStatusAsync(session.Id, "Running"); // ← 두 번째 SaveChanges
|
||||
```
|
||||
|
||||
이 과정에서 EF Core가 동일한 엔티티에 대해 두 번의 `SaveChangesAsync`를 호출하면서 엔티티 상태 관리에 문제가 발생했습니다.
|
||||
|
||||
## 수정 내용
|
||||
|
||||
### 1. ExperionDbContext.cs (`src/Infrastructure/Database/ExperionDbContext.cs:741`)
|
||||
|
||||
**변경 전:**
|
||||
```csharp
|
||||
public async Task<FastSession> CreateFastSessionAsync(FastSessionCreateRequest request)
|
||||
{
|
||||
var session = new FastSession
|
||||
{
|
||||
Name = request.Name,
|
||||
SamplingMs = request.SamplingMs,
|
||||
DurationSec = request.DurationSec,
|
||||
TagList = JsonSerializer.Serialize(request.TagList),
|
||||
StartedAt = DateTime.UtcNow,
|
||||
Status = "Pending", // ❌ Pending으로 설정
|
||||
RowCount = 0,
|
||||
RetentionDays = request.RetentionDays,
|
||||
Pinned = false
|
||||
};
|
||||
_ctx.FastSessions.Add(session);
|
||||
await _ctx.SaveChangesAsync();
|
||||
return session;
|
||||
}
|
||||
```
|
||||
|
||||
**변경 후:**
|
||||
```csharp
|
||||
public async Task<FastSession> CreateFastSessionAsync(FastSessionCreateRequest request)
|
||||
{
|
||||
var session = new FastSession
|
||||
{
|
||||
Name = request.Name,
|
||||
SamplingMs = request.SamplingMs,
|
||||
DurationSec = request.DurationSec,
|
||||
TagList = JsonSerializer.Serialize(request.TagList),
|
||||
StartedAt = DateTime.UtcNow,
|
||||
Status = "Running", // ✅ Running으로 설정
|
||||
RowCount = 0,
|
||||
RetentionDays = request.RetentionDays,
|
||||
Pinned = false
|
||||
};
|
||||
_ctx.FastSessions.Add(session);
|
||||
await _ctx.SaveChangesAsync();
|
||||
return session;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. ExperionFastService.cs (`src/Infrastructure/OpcUa/ExperionFastService.cs:111`)
|
||||
|
||||
**변경 전:**
|
||||
```csharp
|
||||
_sessions[session.Id] = ctx;
|
||||
await db.UpdateFastSessionStatusAsync(session.Id, "Running"); // ❌ 중복 호출
|
||||
|
||||
_logger.LogInformation("[Fast] 세션 {Id} 시작 — 태그 {Count}개, {Ms}ms, {Sec}s",
|
||||
session.Id, request.TagList.Length, request.SamplingMs, request.DurationSec);
|
||||
```
|
||||
|
||||
**변경 후:**
|
||||
```csharp
|
||||
_sessions[session.Id] = ctx;
|
||||
|
||||
_logger.LogInformation("[Fast] 세션 {Id} 시작 — 태그 {Count}개, {Ms}ms, {Sec}s",
|
||||
session.Id, request.TagList.Length, request.SamplingMs, request.DurationSec);
|
||||
```
|
||||
|
||||
## 검증
|
||||
|
||||
### 빌드 검증
|
||||
```bash
|
||||
dotnet build src/Web/ExperionCrawler.csproj --no-restore -v q
|
||||
```
|
||||
- **결과:** Build succeeded (0 Error, 9 Warning)
|
||||
- **Warning:** null reference 관련 경고 (기존 코드)
|
||||
|
||||
### 커밋
|
||||
```
|
||||
fix: fastSession 시작 시 엔티티 변경 오류 수정 - CreateFastSessionAsync에서 Status를 Pending에서 Running으로 변경
|
||||
```
|
||||
- 커밋 해시: `6689612`
|
||||
- 변경 파일: `ExperionDbContext.cs`, `ExperionFastService.cs`
|
||||
|
||||
## 영향 범위
|
||||
|
||||
### 수정된 파일
|
||||
1. [`src/Infrastructure/Database/ExperionDbContext.cs`](src/Infrastructure/Database/ExperionDbContext.cs:732)
|
||||
2. [`src/Infrastructure/OpcUa/ExperionFastService.cs`](src/Infrastructure/OpcUa/ExperionFastService.cs:68)
|
||||
|
||||
### 영향을 받는 기능
|
||||
- fastSession 신규 생성
|
||||
- fastSession 시작
|
||||
- fastSession 목록 조회
|
||||
|
||||
## 참고 사항
|
||||
|
||||
### Status 허용값
|
||||
`FastSession.Status` 필드는 다음 값만 허용합니다:
|
||||
- `Pending` - 대기 중
|
||||
- `Running` - 실행 중
|
||||
- `Completed` - 완료
|
||||
- `Cancelled` - 취소
|
||||
- `Failed` - 실패
|
||||
- `RowLimitReached` - 행 제한 도달
|
||||
|
||||
### 왜 "Running"으로 변경했는가?
|
||||
`CreateFastSessionAsync`는 세션을 생성하고 즉시 실행 상태로 만들기 때문에 `Status`를 `"Running"`으로 설정했습니다. `ExperionFastService.StartSessionAsync`에서 이미 `UpdateFastSessionStatusAsync`를 호출하여 `"Running"`으로 변경하는 로직이 있었기 때문에, 이를 `CreateFastSessionAsync`로 이동시켜 중복 호출을 제거했습니다.
|
||||
|
||||
## 관련 문서
|
||||
- [`ExperionEntities.cs`](src/Core/Domain/Entities/ExperionEntities.cs:101) - FastSession 엔티티 정의
|
||||
- [`ExperionControllers.cs`](src/Web/Controllers/ExperionControllers.cs:672) - fastSession API 컨트롤러
|
||||
- [`app.js`](src/Web/wwwroot/js/app.js:2102) - 프론트엔드 fastStart 함수
|
||||
Reference in New Issue
Block a user