feat(sync): 이벤트 구동 실시간 동기화 — 로컬 IPC 시그널 (PD님 직접 제안)
## 배경 이전 커밋 433290f의 "throttle 30초 단축" 안은 PD님이 직접 반려: "30초 polling은 네트워크 부하 유발 + 근본 해결 아님. 대신 공유할 사항 발생 시 플래그 데이터 갱신 → 수신 측이 플래그만 체크" ## 채택 구조 (PD님 제안 그대로 반영) - 주 동기화: 로컬 IPC 시그널 파일 (~/.claude/.nerdnavis_bus/signal_<repo>) - push 측: sync_signal.sh update 로 HEAD·timestamp 기록 - 수신 측: UserPromptSubmit hook에서 sync_signal.sh check - 플래그 미변경 시 → 네트워크 호출 0 (즉시 종료) - 플래그 변경 시 → fetch + stash/pop + ff→non-ff merge fallback ## 신설 스크립트 - scripts/sync_signal.sh (update/check 모드) - scripts/sync_push.sh (push + 시그널 갱신 묶음) ## 조정 - scripts/git_fetch_throttle.sh 역할 변경: 주 방식 실패·다른 PC push 대비 fallback - throttle 30s → 300s 복원 (네트워크 부하 제거) ## Hook 편입 - UserPromptSubmit hook 순서: (1) sync_signal.sh check → (2) git_fetch_throttle.sh (fallback) ## 네트워크 비용 - 이전(polling): 매 30초 강제 fetch - 현재(이벤트): 플래그 변경 시에만 fetch (변화 없으면 비용 0) ## 노하우 - memory/feedback_realtime_sync_gap.md 갱신 (이벤트 방식 최종 채택) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
433290ffcc
commit
31410bd146
|
|
@ -108,6 +108,10 @@
|
|||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash scripts/sync_signal.sh check 2>/dev/null || true"
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash scripts/git_fetch_throttle.sh 2>/dev/null || true"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#!/bin/bash
|
||||
# UserPromptSubmit hook — 실시간 원격 동기화 (2026-04-17 강화)
|
||||
# UserPromptSubmit hook — 보조(fallback) 원격 동기화
|
||||
# 변경 이력:
|
||||
# - 2026-04-15: 5분 throttle fetch + ff-only merge (초기)
|
||||
# - 2026-04-17: throttle 30초로 단축 + 자동 stash/pop + merge 강화
|
||||
# (PD님 지시: "항상 실시간으로 공유되어서 다른 세션에서도 확인")
|
||||
# - 2026-04-17 AM: throttle 30초 단축 (polling 시도)
|
||||
# - 2026-04-17 PM: 300초 복원. PD님 지적 "30초 polling은 네트워크 부하 + 근본 해결 아님".
|
||||
# 주 동기화는 scripts/sync_signal.sh (로컬 IPC 시그널) 담당. 본 스크립트는
|
||||
# 시그널이 없거나 다른 PC에서 push된 경우를 위한 fallback.
|
||||
|
||||
THROTTLE_DIR="$HOME/.claude/.nerdnavis_throttle"
|
||||
mkdir -p "$THROTTLE_DIR" 2>/dev/null
|
||||
|
|
@ -13,7 +15,7 @@ GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
|
|||
|
||||
REPO_HASH=$(echo "$GIT_DIR" | sha1sum 2>/dev/null | cut -d' ' -f1)
|
||||
THROTTLE_FILE="$THROTTLE_DIR/last_fetch_$REPO_HASH"
|
||||
THROTTLE_SECONDS=30 # 2026-04-17: 300 → 30초 (실시간 동기화 보장)
|
||||
THROTTLE_SECONDS=300 # fallback 역할 — 주 동기화는 sync_signal.sh
|
||||
|
||||
if [ -f "$THROTTLE_FILE" ]; then
|
||||
LAST=$(cat "$THROTTLE_FILE" 2>/dev/null || echo 0)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# sync_push.sh — 자동 push + 시그널 갱신 일괄 실행
|
||||
#
|
||||
# C20-1-A 자동 push 정책 이행 표준 절차:
|
||||
# git push origin main → sync_signal.sh update (로컬 IPC 시그널 갱신)
|
||||
#
|
||||
# PM은 업무 완료 시 본 스크립트 1회 실행으로 push·시그널 갱신 동시 수행.
|
||||
|
||||
cd "$(dirname "$0")/.." 2>/dev/null
|
||||
|
||||
BRANCH="${1:-main}"
|
||||
|
||||
echo "▶️ git push origin $BRANCH"
|
||||
if git push origin "$BRANCH" 2>&1 | tail -3; then
|
||||
echo "✅ push 완료"
|
||||
else
|
||||
echo "❌ push 실패 — 시그널 갱신 건너뜀"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bash scripts/sync_signal.sh update
|
||||
echo "📡 시그널 갱신 완료 — 다른 세션이 다음 프롬프트에서 즉시 감지"
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#!/bin/bash
|
||||
# sync_signal.sh — 로컬 IPC 시그널 기반 실시간 동기화
|
||||
#
|
||||
# 설계 (2026-04-17 PD님 직접 제안):
|
||||
# polling 방식(throttle fetch)은 네트워크 부하 유발 + 근본 해결 아님.
|
||||
# 대신 "공유할 사항 발생 시 플래그 데이터 갱신 → 수신 측이 플래그만 체크"
|
||||
# 구조로 전환. 플래그 변경 감지 시에만 pull 수행하므로 네트워크 비용 최소화.
|
||||
#
|
||||
# 사용:
|
||||
# bash sync_signal.sh update # push 성공 시 호출: 플래그 파일 갱신
|
||||
# bash sync_signal.sh check # UserPromptSubmit hook: 플래그 변경 시 pull
|
||||
|
||||
BUS_DIR="$HOME/.claude/.nerdnavis_bus"
|
||||
mkdir -p "$BUS_DIR" 2>/dev/null
|
||||
|
||||
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
|
||||
[ -z "$GIT_DIR" ] && exit 0
|
||||
|
||||
REPO_HASH=$(echo "$GIT_DIR" | sha1sum 2>/dev/null | cut -d' ' -f1)
|
||||
SIGNAL_FILE="$BUS_DIR/signal_$REPO_HASH"
|
||||
SESSION_LAST_FILE="$BUS_DIR/last_seen_$REPO_HASH.$$"
|
||||
|
||||
MODE="${1:-check}"
|
||||
|
||||
# ============================================================
|
||||
# update 모드: push 성공 후 호출. 로컬 HEAD + timestamp를 시그널에 기록
|
||||
# ============================================================
|
||||
if [ "$MODE" = "update" ]; then
|
||||
HEAD=$(git rev-parse HEAD 2>/dev/null)
|
||||
if [ -n "$HEAD" ]; then
|
||||
echo "$HEAD $(date +%s)" > "$SIGNAL_FILE"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# check 모드: 플래그 파일 변경 감지 시에만 pull (네트워크 비용 최소화)
|
||||
# ============================================================
|
||||
|
||||
[ -f "$SIGNAL_FILE" ] || exit 0
|
||||
|
||||
CURRENT=$(cat "$SIGNAL_FILE" 2>/dev/null)
|
||||
LAST=$(cat "$SESSION_LAST_FILE" 2>/dev/null)
|
||||
|
||||
# 플래그가 자기 세션이 마지막 본 것과 같으면 — 네트워크 호출 없이 종료
|
||||
if [ "$CURRENT" = "$LAST" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 플래그 변경 감지 → fetch + merge 수행
|
||||
CURRENT_HEAD=$(echo "$CURRENT" | awk '{print $1}')
|
||||
LOCAL_HEAD=$(git rev-parse HEAD 2>/dev/null)
|
||||
|
||||
# 이미 로컬이 최신이면 (스스로 push한 세션) — 플래그만 동기화
|
||||
if [ "$CURRENT_HEAD" = "$LOCAL_HEAD" ]; then
|
||||
echo "$CURRENT" > "$SESSION_LAST_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git fetch origin 2>/dev/null
|
||||
|
||||
CHANGES=$(git log --oneline HEAD..origin/main 2>/dev/null | head -5)
|
||||
if [ -n "$CHANGES" ]; then
|
||||
echo "📡 [signal-sync] 플래그 변경 감지 — 원격 변경 자동 반영:"
|
||||
echo "$CHANGES"
|
||||
|
||||
# 로컬 미커밋 안전 stash
|
||||
STASHED=0
|
||||
if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then
|
||||
if git stash push -u -m "signal-sync-$(date +%s)" > /dev/null 2>&1; then
|
||||
STASHED=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if git merge origin/main --no-edit --ff-only 2>/dev/null; then
|
||||
echo "✅ 실시간 동기화 완료 (fast-forward)"
|
||||
elif git merge origin/main --no-edit 2>/dev/null; then
|
||||
echo "✅ 실시간 동기화 완료 (merge commit)"
|
||||
else
|
||||
echo "⚠️ 자동 merge 실패 — 수동 해결 필요 (git merge origin/main)"
|
||||
git merge --abort 2>/dev/null
|
||||
fi
|
||||
|
||||
if [ "$STASHED" -eq 1 ]; then
|
||||
git stash pop > /dev/null 2>&1 || echo "⚠️ stash pop 실패 — git stash list 확인 필요"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$CURRENT" > "$SESSION_LAST_FILE"
|
||||
exit 0
|
||||
Loading…
Reference in New Issue