Bỏ qua đến nội dung chính

Tổng quan kiến trúc

Tham khảo design choices từ kinh nghiệm thực tế setup AIWS production.

PC (always-on, LAN cáp) Laptop (mobile, wifi)
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ Windows Syncthing :8384 │←──────→│ Windows Syncthing :8384 │
│ ├─ claude-state │ TLS │ ├─ claude-state │
│ │ → C:\Users\<u>\.claude\ │ P2P │ │ │
│ └─ code-public-lan │ │ └─ code-public-lan │
│ → D:\Public LAN Folder\ │ │ │
│ │ │ │
│ ┌─ WSL Ubuntu ──────────────┐ │ │ ┌─ WSL Ubuntu ──────────────┐ │
│ │ WSL Syncthing :8385 │←─┼────────┼─→│ WSL Syncthing :8385 │ │
│ │ (BEP 22001, mirrored mode) │ │ │ │ (BEP 22001) │ │
│ │ │ │ │ │ │ │
│ │ └─ wsl-projects │ │ │ │ └─ wsl-projects │ │
│ │ → /home/<u>/projects/ │ │ │ │ → /home/<u>/projects/ │ │
│ └────────────────────────────┘ │ │ └────────────────────────────┘ │
└─────────────────────────────────┘ └─────────────────────────────────┘

Design decisions:

Quyết định 1: 2 instance Syncthing mỗi máy (Windows + WSL)

Phần tiêu đề “Quyết định 1: 2 instance Syncthing mỗi máy (Windows + WSL)”

Alternative không chọn: Single Windows Syncthing access cả Windows + WSL paths qua \\wsl.localhost\.

Rationale:

  • 9P protocol read WSL files từ Windows = cực chậm (~33 MB/min vs native 3952 MB/min, 120x slower)
  • WSL native paths = ext4 native speed
  • Trade-off: 2 instances RAM ~200 MB vs gain 120x performance trên WSL folders

Cost: 2 Web UIs (port 8384 + 8385), 2 Device IDs per máy, 4 Device IDs total network.

Alternative không chọn: NAT’d default WSL networking + port forwarding.

Rationale với mirrored:

  • WSL processes share host LAN IP — laptop’s WSL reach PC’s WSL trực tiếp
  • No netsh portproxy maintenance
  • WSL IP không thay đổi sau reboot (always = host IP)
  • Better cho cross-WSL sync

Cost:

  • wsl --shutdown 1 lần khi enable (n8n down 30-60s, auto-restart)
  • Một số apps có thể cần re-config nếu rely on NAT’d 172.x

Khi nào KHÔNG dùng mirrored: Win11 < 22H2, hoặc apps phụ thuộc NAT’d networking.

Quyết định 3: Phân bổ port 8384/22000 so với 8385/22001

Phần tiêu đề “Quyết định 3: Phân bổ port 8384/22000 so với 8385/22001”
ServiceWindowsWSL
GUI Web UI8384 (default)8385
BEP TCP+QUIC22000 (default)22001
Local discovery21027 (default)21028

Rationale: với mirrored mode, WSL share host port space → conflict nếu cả 2 đều dùng 22000.

Why next sequential numbers (84→85, 22000→22001): dễ nhớ, no clash với well-known ports khác.

Quyết định 4: Đồng bộ cả ~/.claude/ hay từng subfolder

Phần tiêu đề “Quyết định 4: Đồng bộ cả ~/.claude/ hay từng subfolder”

Sync whole (chosen):

  • ✅ Single folder rule, ignore patterns đơn giản
  • .credentials.json auto-sync (OAuth tokens)
  • ❌ Per-machine state (session-env/, shell-snapshots/) phải ignore

Alternative — only projects/ + skills/:

  • ✅ Cleaner separation
  • .credentials.json outside → manual handle separately
  • ❌ Settings, memory cần extra folders

→ Whole + ignore = pragmatic.

Quyết định 5: KHÔNG đồng bộ .claude.json (file đơn)

Phần tiêu đề “Quyết định 5: KHÔNG đồng bộ .claude.json (file đơn)”

Why: Syncthing v2 không support sync single file. File .claude.json (~23KB) chứa mcpServers config + OAuth account info.

Workaround: copy manually qua shared folder khi update (rare event, vd add MCP).

Alternative: tạo wrapper folder + symlink (work nhưng more setup).

Quyết định 6: Ignore .git/objects/pack/ HAY KHÔNG?

Phần tiêu đề “Quyết định 6: Ignore .git/objects/pack/ HAY KHÔNG?”

Sync .git/ whole (chosen):

  • ✅ Preserve uncommitted local commits
  • ❌ +5-10 GB storage cho large repos

Alternative — ignore .git/:

  • ✅ Smaller sync footprint
  • ❌ Mất uncommitted local commits → mỗi máy git clone lại

→ Storage cheap, commits valuable. Sync whole.

Why:

  • PC always-on có Cloudflare tunnel n8n.aiws.vn
  • DB Postgres: file-level sync RISKY (binary, locked, corruption-prone)
  • Single source of truth cho workflows + executions
  • Laptop access via n8n.aiws.vn URL → cùng instance

Cost: Khi PC tắt → laptop không access n8n. Mitigation: pg_dump weekly backup sync xuống laptop cho emergency restore.

Risk known: 1 máy refresh token → invalidate trên máy kia.

Why acceptable:

  • User chỉ work 1 máy at a time → race condition rare
  • Re-login ~30 giây nếu happen
  • Convenience > 30s occasional re-login

KHÔNG acceptable case: 2 users share account đồng thời 2 máy → phải KHÔNG sync .credentials.json.

PC's Syncthing
↓ TLS 1.3 over TCP/QUIC
↓ Direct connection (no relay)
Laptop's Syncthing
Path: PC IP (192.168.1.14) ↔ Laptop IP (192.168.1.16)
Speed: LAN gigabit ~80-100 MB/s effective
Latency: &lt;1 ms
PC's Syncthing
↓ Connect to public Syncthing relay
↓ Relay forwards encrypted traffic
Laptop's Syncthing (different LAN)
Path: PC → relay → Laptop (relay does not decrypt)
Speed: Limited by upstream bandwidth + relay throughput
Latency: 50-300 ms

Both encrypted end-to-end. Relay servers cannot read content.

1. User edits file in synced folder (PC side)
2. OS file watcher fires event (inotify/ReadDirectoryChangesW)
3. Syncthing detects change → re-hash file blocks
4. Syncthing publishes index update to peer (Laptop)
5. Laptop compares index → detects new blocks
6. Laptop requests blocks from PC
7. PC sends blocks (encrypted)
8. Laptop writes blocks to file
9. Sync complete

Total time on LAN: <1s for small files, seconds for MB-sized.

Both peers offline → both edit same file → both come online
Syncthing detect: file modified time + content hash differ
Keep both versions:
hello.txt ← latest from "winning" peer
hello.sync-conflict-&lt;date&gt;-&lt;peer&gt;.txt ← other peer's version

“Winning” peer = đang receive last (alphabetical Device ID tiebreaker).

User manually review + resolve.