# Datacollector - processed 카운터 정체 및 엔진 루프 정지 감시 보강

- 작성 시각: 2026-04-25 22:52:25 KST
- 프로젝트: `/Volumes/Data/project/Antigravity/Datacollector`
- 관련 파일: `src/lib/engine.ts`, `src/components/AgentDashboard.tsx`

## 상황

사용자는 작업이 되는 것처럼 보이지만 `processed` 수치가 계속 오르지 않고, 서버를 재시작하면 1개가 추가된 뒤 다시 멈춘 것처럼 보인다고 보고했다.

## 확인한 내용

브리지 서버 상태는 정상이고 `/api/health` 기준 `pendingRequests`도 0이었다. 따라서 서버 요청이 계속 물려 있는 문제보다는 프론트엔드 엔진 루프가 한 번 처리한 뒤 다음 반복으로 자연스럽게 이어지지 않는 가능성이 높았다.

코드상 `processedCount`는 `executeTask()`가 마크다운 생성까지 끝낸 뒤 `store.incrementProcessed()`를 호출할 때만 오른다. 즉 카운터가 오르지 않는다는 것은 다음 중 하나일 가능성이 있다.

- 다음 작업 합성이 아직 완료되지 않았다.
- 프론트엔드 엔진 루프 타이머가 끊겼다.
- UI 상태는 `running`인데 엔진 내부 싱글톤의 루프가 실제로는 잠든 상태가 되었다.

## 조치

`src/lib/engine.ts`:

- `isLoopActive`, `lastActivityAt`, `loopTimer`를 추가했다.
- `runLoop()` 중복 실행을 막으면서도, 루프가 잠든 경우 다시 깨울 수 있게 했다.
- `kickIfStalled()`를 추가해 `running` 상태인데 45초 이상 루프 활동이 없으면 자동으로 다음 루프를 시작한다.
- 다음 루프 예약을 `scheduleNextLoop()`로 통합해 타이머를 추적할 수 있게 했다.
- 작업 완료 후 `processedCount`가 반영된 값을 로그로 남기도록 했다.

`src/components/AgentDashboard.tsx`:

- 상태가 `running`일 때 15초마다 엔진 heartbeat를 실행한다.
- 엔진 루프가 잠든 것으로 판단되면 `kickIfStalled()`가 자동으로 다시 깨운다.

## 검증

다음 검증을 완료했다.

```bash
npm run lint
```

결과:

- TypeScript 검사 통과

## 운영 메모

이제 작업 하나가 완료될 때 Mission Telemetry에 다음 형태의 로그가 추가된다.

```text
[ENGINE] '토픽명' 처리 카운트 반영 완료: N
```

이 로그가 보이면 `processed` 값도 함께 올라가는 것이 정상이다. 만약 이 로그가 보이지 않고 `최종 데이터 합성 중...` 이후 오래 멈춘다면, 그때는 카운터 문제가 아니라 NotebookLM 합성 요청이 오래 걸리거나 실패 응답을 기다리는 상태로 봐야 한다.
