hotfix(critical): single-instance lock — SQLite race 방지 (v0.2.5) #23

Merged
altair823 merged 1 commits from hotfix/single-instance-lock into main 2026-05-04 15:48:06 +00:00
Owner

Summary

Critical hotfix. 앱 아이콘 클릭 시 새 process 가 매번 뜨면서 트레이 아이콘 여러 개 + SQLite/AiWorker/HealthChecker 동시 접근 → 데이터 corruption 위험. dogfood 도중 발견.

Root cause

app.requestSingleInstanceLock() 호출 부재. Electron default 가 multi-instance 이므로 .exe 실행마다 별도 main process. 이로 인해:

  • SQLite WAL 동시 write → DB 손상 가능
  • AiWorker 중복 polling → 같은 pending_jobs 두 process 가 처리 (race)
  • HealthChecker 중복 polling → Ollama 부하 + telemetry 이중 emit
  • settings.json atomic write race → temp/rename 충돌
  • 트레이 아이콘 여러 개 → 사용자 혼동

Fix

src/main/index.ts 진입점 (whenReady 직전):

const gotLock = app.requestSingleInstanceLock();
if (!gotLock) {
  app.quit();
} else {
  app.on('second-instance', () => {
    const win = getInboxWindow();
    if (win) {
      if (win.isMinimized()) win.restore();
      if (!win.isVisible()) win.show();
      win.focus();
    } else {
      createInboxWindow();
    }
  });
}
  • 첫 인스턴스만 lock 획득 → 진행
  • 이후 .exe 실행 시도 → gotLock = falseapp.quit() 즉시 종료
  • 첫 인스턴스의 second-instance 이벤트가 trigger → 기존 inbox 창 restore + show + focus (사용자 의도 = "앱 보기")

Gates

  • typecheck 0
  • 단위 413/413
  • e2e 1/1

Version

0.2.40.2.5 (critical hotfix patch).

Test Plan

  • typecheck / unit / e2e
  • dogfood: v0.2.5 설치 후 작업관리자에서 ollama tray + Inkling 종료
  • dogfood: 시작 메뉴 → Inkling 클릭 → 1개 process, 1개 트레이 아이콘
  • dogfood: 시작 메뉴 → Inkling 다시 클릭 → 새 process X, 기존 inbox 창 focus
  • dogfood: 트레이 아이콘 클릭 → inbox 창 정상 토글

다음

머지 후 binary v0.2.5 빌드 (Windows + Mac) + Gitea release 즉시 — 데이터 안전 영향이라 v0.2.4 사용자 즉시 업그레이드 권장.

## Summary **Critical hotfix.** 앱 아이콘 클릭 시 새 process 가 매번 뜨면서 트레이 아이콘 여러 개 + **SQLite/AiWorker/HealthChecker 동시 접근 → 데이터 corruption 위험**. dogfood 도중 발견. ## Root cause `app.requestSingleInstanceLock()` 호출 부재. Electron default 가 multi-instance 이므로 `.exe` 실행마다 별도 main process. 이로 인해: - **SQLite WAL 동시 write** → DB 손상 가능 - **AiWorker 중복 polling** → 같은 pending_jobs 두 process 가 처리 (race) - **HealthChecker 중복 polling** → Ollama 부하 + telemetry 이중 emit - **settings.json atomic write race** → temp/rename 충돌 - **트레이 아이콘 여러 개** → 사용자 혼동 ## Fix `src/main/index.ts` 진입점 (whenReady 직전): ```typescript const gotLock = app.requestSingleInstanceLock(); if (!gotLock) { app.quit(); } else { app.on('second-instance', () => { const win = getInboxWindow(); if (win) { if (win.isMinimized()) win.restore(); if (!win.isVisible()) win.show(); win.focus(); } else { createInboxWindow(); } }); } ``` - 첫 인스턴스만 lock 획득 → 진행 - 이후 .exe 실행 시도 → `gotLock = false` → `app.quit()` 즉시 종료 - 첫 인스턴스의 `second-instance` 이벤트가 trigger → 기존 inbox 창 restore + show + focus (사용자 의도 = "앱 보기") ## Gates - typecheck 0 - 단위 413/413 - e2e 1/1 ## Version `0.2.4` → `0.2.5` (critical hotfix patch). ## Test Plan - [x] typecheck / unit / e2e - [ ] dogfood: v0.2.5 설치 후 작업관리자에서 ollama tray + Inkling 종료 - [ ] dogfood: 시작 메뉴 → Inkling 클릭 → 1개 process, 1개 트레이 아이콘 - [ ] dogfood: 시작 메뉴 → Inkling 다시 클릭 → 새 process X, 기존 inbox 창 focus - [ ] dogfood: 트레이 아이콘 클릭 → inbox 창 정상 토글 ## 다음 머지 후 binary v0.2.5 빌드 (Windows + Mac) + Gitea release 즉시 — 데이터 안전 영향이라 v0.2.4 사용자 즉시 업그레이드 권장.
altair823 added 1 commit 2026-05-04 15:43:48 +00:00
dogfood 발견 — 앱 아이콘 클릭 시마다 새 process 가 떠서 트레이 아이콘 여러 개,
SQLite 동시 접근 + AiWorker 중복 처리 + HealthChecker 중복 polling 등
**데이터 corruption 위험**.

원인: app.requestSingleInstanceLock() 호출 부재. Electron default 가
multi-instance 라 .exe 실행마다 별도 process.

Fix:
- app.requestSingleInstanceLock() 첫 줄에서 호출
- 두 번째 인스턴스 → app.quit() 즉시 종료
- 'second-instance' 이벤트 → 기존 inbox 창 restore + show + focus
  (사용자 의도는 "앱 보기" 라 가정)

게이트: typecheck 0 / 단위 413 / e2e 1
version: 0.2.4 → 0.2.5 (critical hotfix patch)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author
Owner

Critical hotfix review — APPROVE

항목 결과
Critical 0
Important 1 (hidden-start race — acknowledge, v0.2.6 backlog)
Minor 3 (모두 acknowledge / 무관)
Nit 1 (explicit return — 현재 else 가드로 OK)
Gates typecheck 0 / 단위 413 / e2e 1

Important (defer to v0.2.6)

Hidden-start race: NSIS installer 가 설치 직후 inkling.exe (사용자 클릭) + autostart inkling.exe --hidden 두 instance 를 짧은 간격에 spawn 시 — 첫 lock 보유자에 따라 visible 여부 race. 본 cut 의 second-instance handler 는 무조건 inbox 창 띄움 (사용자 클릭 = 보고 싶다는 강한 시그널 가정). 매우 드문 시나리오 + lock 자체는 정상 동작. v0.2.6 에서 requestSingleInstanceLockadditionalData arg + second-instance(event, argv, cwd, additionalData) 로 hidden flag 전달 → 두 번째가 hidden 이면 창 안 띄움 정책 검토.

Skip (acknowledge)

  • second-instance args ignore: file-association / CLI args 미사용 — 후속 deeplink 시 재방문
  • e2e smoke 영향: 격리 userDataDir 라 무관, 단 가이드에 "실설치 앱 종료 후" 추가 검토 (코드 변경 X)
  • macOS activate 충돌: macOS 는 Dock 자체가 single-instance — 무관

Verdict

APPROVE — Critical 데이터 안전 hotfix. 즉시 머지 권장. Important 는 매우 드문 시나리오 + lock 정상 동작이라 v0.2.6 검토.

머지 후 binary v0.2.5 빌드 + Gitea release.

## Critical hotfix review — APPROVE | 항목 | 결과 | |---|---| | Critical | 0 | | Important | 1 (hidden-start race — acknowledge, v0.2.6 backlog) | | Minor | 3 (모두 acknowledge / 무관) | | Nit | 1 (explicit return — 현재 else 가드로 OK) | | Gates | typecheck 0 / 단위 413 / e2e 1 | ### Important (defer to v0.2.6) **Hidden-start race**: NSIS installer 가 설치 직후 `inkling.exe` (사용자 클릭) + autostart `inkling.exe --hidden` 두 instance 를 짧은 간격에 spawn 시 — 첫 lock 보유자에 따라 visible 여부 race. 본 cut 의 `second-instance` handler 는 무조건 inbox 창 띄움 (사용자 클릭 = 보고 싶다는 강한 시그널 가정). 매우 드문 시나리오 + lock 자체는 정상 동작. v0.2.6 에서 `requestSingleInstanceLock` 의 `additionalData` arg + `second-instance(event, argv, cwd, additionalData)` 로 hidden flag 전달 → 두 번째가 hidden 이면 창 안 띄움 정책 검토. ### Skip (acknowledge) - second-instance args ignore: file-association / CLI args 미사용 — 후속 deeplink 시 재방문 - e2e smoke 영향: 격리 userDataDir 라 무관, 단 가이드에 "실설치 앱 종료 후" 추가 검토 (코드 변경 X) - macOS activate 충돌: macOS 는 Dock 자체가 single-instance — 무관 ### Verdict **APPROVE** — Critical 데이터 안전 hotfix. 즉시 머지 권장. Important 는 매우 드문 시나리오 + lock 정상 동작이라 v0.2.6 검토. 머지 후 binary v0.2.5 빌드 + Gitea release.
altair823 merged commit 8f2b9adb3a into main 2026-05-04 15:48:06 +00:00
altair823 deleted branch hotfix/single-instance-lock 2026-05-04 15:48:08 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: altair823-org/inkling#23