@kood/claude-code 0.6.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +7 -1
- package/package.json +1 -1
- package/templates/.claude/agents/analyst.md +5 -0
- package/templates/.claude/agents/architect.md +5 -0
- package/templates/.claude/agents/build-fixer.md +1 -0
- package/templates/.claude/agents/code-reviewer.md +1 -0
- package/templates/.claude/agents/critic.md +4 -0
- package/templates/.claude/agents/deep-executor.md +1 -0
- package/templates/.claude/agents/dependency-manager.md +2 -0
- package/templates/.claude/agents/deployment-validator.md +2 -0
- package/templates/.claude/agents/designer.md +2 -0
- package/templates/.claude/agents/document-writer.md +3 -0
- package/templates/.claude/agents/explore.md +1 -0
- package/templates/.claude/agents/git-operator.md +2 -0
- package/templates/.claude/agents/implementation-executor.md +2 -0
- package/templates/.claude/agents/ko-to-en-translator.md +3 -0
- package/templates/.claude/agents/lint-fixer.md +2 -0
- package/templates/.claude/agents/planner.md +3 -0
- package/templates/.claude/agents/pm.md +349 -0
- package/templates/.claude/agents/qa-tester.md +1 -0
- package/templates/.claude/agents/refactor-advisor.md +4 -0
- package/templates/.claude/agents/researcher.md +9 -1
- package/templates/.claude/agents/scientist.md +1 -0
- package/templates/.claude/agents/security-reviewer.md +1 -0
- package/templates/.claude/agents/tdd-guide.md +1 -0
- package/templates/.claude/agents/vision.md +1 -0
- package/templates/.claude/instructions/agent-patterns/agent-teams-usage.md +376 -0
- package/templates/.claude/instructions/sourcing/reliable-search.md +49 -2
- package/templates/.claude/scripts/agent-teams/check-availability.sh +238 -0
- package/templates/.claude/scripts/agent-teams/setup-tmux.sh +125 -0
- package/templates/.claude/skills/agent-teams-setup/SKILL.md +460 -0
- package/templates/.claude/skills/brainstorm/SKILL.md +1 -0
- package/templates/.claude/skills/bug-fix/SKILL.md +1 -0
- package/templates/.claude/skills/crawler/SKILL.md +2 -0
- package/templates/.claude/skills/docs-creator/SKILL.md +1 -0
- package/templates/.claude/skills/docs-fetch/SKILL.md +6 -4
- package/templates/.claude/skills/docs-refactor/SKILL.md +1 -0
- package/templates/.claude/skills/elon-musk/SKILL.md +1 -0
- package/templates/.claude/skills/execute/SKILL.md +1 -0
- package/templates/.claude/skills/feedback/SKILL.md +1 -0
- package/templates/.claude/skills/figma-to-code/SKILL.md +1 -0
- package/templates/.claude/skills/genius-thinking/SKILL.md +1 -0
- package/templates/.claude/skills/global-uiux-design/SKILL.md +1 -0
- package/templates/.claude/skills/korea-uiux-design/SKILL.md +1 -0
- package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +1 -0
- package/templates/.claude/skills/plan/SKILL.md +1 -0
- package/templates/.claude/skills/prd/SKILL.md +1 -0
- package/templates/.claude/skills/project-optimizer/AGENTS.md +275 -0
- package/templates/.claude/skills/project-optimizer/SKILL.md +375 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-config-centralize.md +66 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-hot-path.md +35 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-interface-segregation.md +51 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-module-boundary.md +42 -0
- package/templates/.claude/skills/project-optimizer/rules/build-cache.md +57 -0
- package/templates/.claude/skills/project-optimizer/rules/build-code-split.md +56 -0
- package/templates/.claude/skills/project-optimizer/rules/build-incremental.md +65 -0
- package/templates/.claude/skills/project-optimizer/rules/build-minify.md +61 -0
- package/templates/.claude/skills/project-optimizer/rules/build-tree-shake.md +60 -0
- package/templates/.claude/skills/project-optimizer/rules/code-complexity.md +65 -0
- package/templates/.claude/skills/project-optimizer/rules/code-dead-elimination.md +32 -0
- package/templates/.claude/skills/project-optimizer/rules/code-duplication.md +54 -0
- package/templates/.claude/skills/project-optimizer/rules/code-error-handling.md +75 -0
- package/templates/.claude/skills/project-optimizer/rules/code-naming.md +52 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-defer-await.md +54 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-parallel.md +90 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-pipeline.md +68 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-pool.md +68 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-lightweight-alt.md +37 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-peer-align.md +44 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-security-audit.md +45 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-unused-removal.md +25 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-version-pin.md +40 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-ci-speed.md +47 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-dev-server.md +35 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-lint-config.md +36 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-test-coverage.md +34 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-type-safety.md +49 -0
- package/templates/.claude/skills/project-optimizer/rules/io-batch-queries.md +67 -0
- package/templates/.claude/skills/project-optimizer/rules/io-cache-layer.md +67 -0
- package/templates/.claude/skills/project-optimizer/rules/io-connection-reuse.md +67 -0
- package/templates/.claude/skills/project-optimizer/rules/io-serialize-minimal.md +61 -0
- package/templates/.claude/skills/project-optimizer/rules/io-stream.md +75 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-bounded-cache.md +65 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-large-data.md +64 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-lazy-init.md +78 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-leak-prevention.md +79 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-pool-reuse.md +70 -0
- package/templates/.claude/skills/ralph/SKILL.md +1 -0
- package/templates/.claude/skills/refactor/SKILL.md +1 -0
- package/templates/.claude/skills/research/SKILL.md +1 -0
- package/templates/.claude/skills/sql-optimizer/SKILL.md +438 -0
- package/templates/.claude/skills/sql-optimizer/orm-patterns.md +218 -0
- package/templates/.claude/skills/startup-validator/SKILL.md +1 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +53 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +94 -27
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +42 -19
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-optimistic-updates.md +109 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-suspense-query.md +74 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-use-hook.md +81 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-react-compiler.md +81 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-beforeload-auth.md +121 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-file-conventions.md +104 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-link-navigation.md +119 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-nested-layouts.md +155 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-path-params.md +89 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-pending-component.md +110 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-preload-strategy.md +91 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-router-context.md +120 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-search-params.md +114 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +1 -1
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-error-boundaries.md +79 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-middleware.md +85 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +56 -21
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-streaming.md +84 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-validator.md +71 -0
- package/templates/.claude/skills/tauri-react-best-practices/AGENTS.md +527 -0
- package/templates/.claude/skills/tauri-react-best-practices/SKILL.md +571 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-barrel-imports.md +140 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-cargo-profile.md +96 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-frontend-treeshake.md +242 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-lazy-components.md +255 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-remove-unused-commands.md +160 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-ci-pipeline.md +269 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-signing.md +207 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-updater.md +226 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-async-commands.md +172 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-batch-commands.md +133 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-binary-response.md +198 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-channel-streaming.md +186 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-error-handling.md +250 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-type-safe.md +227 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-derived-state.md +231 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-functional-setstate.md +191 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-index-maps.md +276 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-lazy-state-init.md +196 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-lifecycle.md +265 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-mobile-compat.md +199 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-permission-scope.md +193 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-error-boundary.md +239 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-event-listener.md +151 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-file-src.md +155 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-invoke-hook.md +139 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-optimistic-update.md +211 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-capability-split.md +205 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-csp.md +207 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-least-privilege.md +106 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-no-wildcard.md +253 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-scope-paths.md +160 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-async-mutex.md +270 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-mutex-pattern.md +265 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-react-sync.md +375 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-single-container.md +275 -0
- package/templates/tanstack-start/docs/architecture.md +238 -167
- package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +777 -38
- package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +549 -37
- package/templates/tanstack-start/docs/library/tanstack-router/index.md +895 -111
- package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +641 -43
- package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +889 -38
- package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +891 -29
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +972 -36
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +1525 -881
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +1099 -20
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +796 -30
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +953 -35
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +371 -15
- package/templates/tauri/CLAUDE.md +189 -0
- package/templates/tauri/docs/guides/distribution.md +261 -0
- package/templates/tauri/docs/guides/getting-started.md +302 -0
- package/templates/tauri/docs/guides/mobile.md +288 -0
- package/templates/tauri/docs/library/tauri/index.md +510 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Limit Concurrency with Pools
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Prevents resource exhaustion, stable throughput
|
|
5
|
+
tags: concurrency, pool, semaphore, rate-limiting, backpressure
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-parallel, io-connection-reuse, memory-bounded-cache]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 동시 실행 수 제한
|
|
11
|
+
|
|
12
|
+
무제한 병렬화는 리소스 고갈을 유발. 커넥션 풀, 세마포어, 워커 풀로 동시 실행 수를 제한합니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (무제한 동시 실행):**
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// 1000개 URL 동시 요청 → 커넥션 고갈, OOM
|
|
18
|
+
const results = await Promise.all(
|
|
19
|
+
urls.map(url => fetch(url))
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**✅ 올바른 예시 (동시 실행 수 제한):**
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// JS/TS (p-limit)
|
|
27
|
+
import pLimit from 'p-limit'
|
|
28
|
+
const limit = pLimit(10) // 최대 10개 동시
|
|
29
|
+
const results = await Promise.all(
|
|
30
|
+
urls.map(url => limit(() => fetch(url)))
|
|
31
|
+
)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
# Python (asyncio.Semaphore)
|
|
36
|
+
sem = asyncio.Semaphore(10)
|
|
37
|
+
async def limited_fetch(url):
|
|
38
|
+
async with sem:
|
|
39
|
+
return await fetch(url)
|
|
40
|
+
|
|
41
|
+
results = await asyncio.gather(*[limited_fetch(url) for url in urls])
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```go
|
|
45
|
+
// Go (worker pool)
|
|
46
|
+
func worker(jobs <-chan string, results chan<- Result) {
|
|
47
|
+
for url := range jobs {
|
|
48
|
+
results <- fetch(url)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 10개 워커 실행
|
|
52
|
+
for i := 0; i < 10; i++ { go worker(jobs, results) }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```rust
|
|
56
|
+
// Rust (tokio::sync::Semaphore)
|
|
57
|
+
let sem = Arc::new(Semaphore::new(10));
|
|
58
|
+
let tasks: Vec<_> = urls.iter().map(|url| {
|
|
59
|
+
let permit = sem.clone().acquire_owned();
|
|
60
|
+
async move {
|
|
61
|
+
let _permit = permit.await.unwrap();
|
|
62
|
+
fetch(url).await
|
|
63
|
+
}
|
|
64
|
+
}).collect();
|
|
65
|
+
let results = futures::future::join_all(tasks).await;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**적정 동시 실행 수:** DB 커넥션 10-25, HTTP 요청 10-50, 파일 I/O 5-20.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Replace Heavy Libraries with Lightweight Alternatives
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: 30-80% bundle/install size reduction
|
|
5
|
+
tags: deps, lightweight, alternative, bundle-size
|
|
6
|
+
languages: all
|
|
7
|
+
related: [build-tree-shake, build-minify]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 무거운 라이브러리 경량 대안으로 교체
|
|
11
|
+
|
|
12
|
+
사용 기능 대비 과도하게 큰 라이브러리를 경량 대안 또는 네이티브 API로 교체합니다.
|
|
13
|
+
|
|
14
|
+
**흔한 교체 대상:**
|
|
15
|
+
|
|
16
|
+
| 무거운 라이브러리 | 경량 대안 | 크기 감소 |
|
|
17
|
+
|-----------------|----------|----------|
|
|
18
|
+
| `moment.js` (300KB) | `date-fns` 또는 `dayjs` (2-7KB) | 97% |
|
|
19
|
+
| `lodash` (72KB) | 네이티브 JS 메서드 / `lodash-es` 직접 import | 90%+ |
|
|
20
|
+
| `axios` (29KB) | `fetch` (내장) / `ky` (3KB) | 90% |
|
|
21
|
+
| `uuid` (12KB) | `crypto.randomUUID()` (내장) | 100% |
|
|
22
|
+
| `chalk` (20KB) | `picocolors` (2KB) | 90% |
|
|
23
|
+
| `express` | `h3` / `Hono` (더 빠르고 작음) | 50%+ |
|
|
24
|
+
|
|
25
|
+
**Python:**
|
|
26
|
+
|
|
27
|
+
| 무거운 | 경량 대안 |
|
|
28
|
+
|-------|----------|
|
|
29
|
+
| `requests` | `httpx` (async 지원) |
|
|
30
|
+
| `beautifulsoup4` | `selectolax` (10x 빠름) |
|
|
31
|
+
| `pandas` (작은 작업) | `polars` (메모리 효율) |
|
|
32
|
+
| `flake8+isort+black` | `ruff` (100x 빠름, 올인원) |
|
|
33
|
+
|
|
34
|
+
**판단 기준:**
|
|
35
|
+
1. 사용하는 기능이 전체의 10% 미만 → 교체 고려
|
|
36
|
+
2. 네이티브 API로 대체 가능 → 교체
|
|
37
|
+
3. 번들 크기 50KB+ 차이 → 교체 고려
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Resolve Peer Dependency Conflicts
|
|
3
|
+
impact: LOW-MEDIUM
|
|
4
|
+
impactDescription: Eliminates runtime version conflicts
|
|
5
|
+
tags: deps, peer, conflict, resolution
|
|
6
|
+
languages: all
|
|
7
|
+
related: [deps-version-pin, deps-security-audit]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Peer Dependency 버전 충돌 해결
|
|
11
|
+
|
|
12
|
+
peer dependency 경고/에러를 해결하여 런타임 버전 충돌을 방지합니다.
|
|
13
|
+
|
|
14
|
+
**감지:**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# npm
|
|
18
|
+
npm ls --all 2>&1 | grep "peer dep"
|
|
19
|
+
npm install # 경고 메시지 확인
|
|
20
|
+
|
|
21
|
+
# yarn
|
|
22
|
+
yarn install # 경고 확인
|
|
23
|
+
|
|
24
|
+
# pnpm
|
|
25
|
+
pnpm install # strict peer deps 기본
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**해결 전략:**
|
|
29
|
+
|
|
30
|
+
| 상황 | 해결 |
|
|
31
|
+
|------|------|
|
|
32
|
+
| 라이브러리 A가 react@18 요구, B가 react@19 요구 | A 업데이트 또는 overrides 사용 |
|
|
33
|
+
| 여러 버전의 같은 라이브러리 설치됨 | `npm ls [pkg]`로 확인, 상위 버전으로 통일 |
|
|
34
|
+
| 호환 불가 | `overrides` (npm) / `resolutions` (yarn) / `overrides` (pnpm) |
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
// package.json - 강제 버전 통일
|
|
38
|
+
{
|
|
39
|
+
"overrides": { "react": "^19.0.0" },
|
|
40
|
+
"resolutions": { "react": "^19.0.0" }
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**원칙:** overrides는 최후 수단. 먼저 라이브러리 업데이트 시도.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Audit Dependencies for Security Vulnerabilities
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Prevent known CVE exploitation
|
|
5
|
+
tags: deps, security, audit, vulnerability, cve
|
|
6
|
+
languages: all
|
|
7
|
+
related: [deps-version-pin]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 보안 취약점 스캔 및 업데이트
|
|
11
|
+
|
|
12
|
+
알려진 보안 취약점이 있는 의존성을 감지하고 업데이트합니다.
|
|
13
|
+
|
|
14
|
+
**스캔 도구:**
|
|
15
|
+
|
|
16
|
+
| 언어 | 도구 | 명령어 |
|
|
17
|
+
|------|------|--------|
|
|
18
|
+
| **JS/TS** | npm audit | `npm audit` / `npm audit fix` |
|
|
19
|
+
| **JS/TS** | yarn audit | `yarn npm audit` |
|
|
20
|
+
| **Python** | pip-audit | `pip-audit` |
|
|
21
|
+
| **Python** | safety | `safety check` |
|
|
22
|
+
| **Go** | govulncheck | `govulncheck ./...` |
|
|
23
|
+
| **Rust** | cargo-audit | `cargo audit` |
|
|
24
|
+
| **범용** | trivy | `trivy fs .` |
|
|
25
|
+
| **범용** | Snyk | `snyk test` |
|
|
26
|
+
|
|
27
|
+
**CI 통합:**
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
# GitHub Actions
|
|
31
|
+
- name: Security audit
|
|
32
|
+
run: npm audit --audit-level=high
|
|
33
|
+
|
|
34
|
+
# Dependabot (자동 PR)
|
|
35
|
+
# .github/dependabot.yml
|
|
36
|
+
version: 2
|
|
37
|
+
updates:
|
|
38
|
+
- package-ecosystem: "npm"
|
|
39
|
+
directory: "/"
|
|
40
|
+
schedule:
|
|
41
|
+
interval: "weekly"
|
|
42
|
+
open-pull-requests-limit: 10
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**원칙:** CI에서 high/critical 취약점 발견 시 빌드 실패 설정.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Remove Unused Dependencies
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Smaller install size, fewer vulnerabilities, faster CI
|
|
5
|
+
tags: deps, unused, cleanup, audit
|
|
6
|
+
languages: all
|
|
7
|
+
related: [build-tree-shake, code-dead-elimination]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 미사용 의존성 제거
|
|
11
|
+
|
|
12
|
+
설치되었지만 코드에서 import/require 되지 않는 패키지를 제거합니다.
|
|
13
|
+
|
|
14
|
+
**감지 도구:**
|
|
15
|
+
|
|
16
|
+
| 언어 | 도구 | 명령어 |
|
|
17
|
+
|------|------|--------|
|
|
18
|
+
| **JS/TS** | knip | `npx knip` |
|
|
19
|
+
| **JS/TS** | depcheck | `npx depcheck` |
|
|
20
|
+
| **Python** | deptry | `deptry .` |
|
|
21
|
+
| **Go** | go mod tidy | `go mod tidy` (자동 정리) |
|
|
22
|
+
| **Rust** | cargo-udeps | `cargo +nightly udeps` |
|
|
23
|
+
| **Java** | gradle-dependency-analysis | Gradle 플러그인 |
|
|
24
|
+
|
|
25
|
+
**주의:** devDependencies (빌드/테스트 도구)는 코드에서 직접 import하지 않아도 필요할 수 있음. 빌드 확인 후 제거.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Pin Production Dependency Versions
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Reproducible builds, no surprise breakages
|
|
5
|
+
tags: deps, version, pin, lock, reproducible
|
|
6
|
+
languages: all
|
|
7
|
+
related: [deps-security-audit, deps-peer-align]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 프로덕션 의존성 버전 고정
|
|
11
|
+
|
|
12
|
+
lockfile을 커밋하고 프로덕션 의존성은 정확한 버전으로 설치합니다.
|
|
13
|
+
|
|
14
|
+
**✅ 필수:**
|
|
15
|
+
|
|
16
|
+
| 파일 | 언어 | Git 커밋 |
|
|
17
|
+
|------|------|---------|
|
|
18
|
+
| `package-lock.json` / `yarn.lock` / `pnpm-lock.yaml` | JS/TS | 필수 |
|
|
19
|
+
| `Cargo.lock` | Rust (바이너리) | 필수 |
|
|
20
|
+
| `go.sum` | Go | 필수 |
|
|
21
|
+
| `poetry.lock` / `uv.lock` | Python | 필수 |
|
|
22
|
+
| `Gemfile.lock` | Ruby | 필수 |
|
|
23
|
+
|
|
24
|
+
**CI에서 lockfile 기반 설치:**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# npm
|
|
28
|
+
npm ci # (npm install 아님!)
|
|
29
|
+
|
|
30
|
+
# yarn
|
|
31
|
+
yarn install --immutable
|
|
32
|
+
|
|
33
|
+
# pnpm
|
|
34
|
+
pnpm install --frozen-lockfile
|
|
35
|
+
|
|
36
|
+
# pip
|
|
37
|
+
pip install -r requirements.txt --no-deps
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**원칙:** `npm install`/`yarn install`은 lockfile을 수정할 수 있으므로 CI에서는 `ci`/`--frozen-lockfile` 사용.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Optimize CI Pipeline Speed
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: 30-70% CI time reduction
|
|
5
|
+
tags: dx, ci, pipeline, speed, cache
|
|
6
|
+
languages: all
|
|
7
|
+
related: [build-cache, build-incremental, dx-test-coverage]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## CI 파이프라인 속도 최적화
|
|
11
|
+
|
|
12
|
+
CI 파이프라인의 불필요한 단계를 제거하고 병렬화/캐싱을 적용합니다.
|
|
13
|
+
|
|
14
|
+
**최적화 전략:**
|
|
15
|
+
|
|
16
|
+
| 전략 | 효과 | 적용 |
|
|
17
|
+
|------|------|------|
|
|
18
|
+
| **의존성 캐시** | 50-80% 설치 시간 감소 | lockfile 해시 기반 캐시 키 |
|
|
19
|
+
| **병렬 단계** | 단계 수에 비례 감소 | lint, test, build 동시 실행 |
|
|
20
|
+
| **변경 파일만** | 대규모 모노레포에서 효과적 | `turbo run --filter=...` |
|
|
21
|
+
| **불필요 단계 제거** | 즉시 효과 | 중복 설치, 불필요 빌드 제거 |
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
# GitHub Actions - 병렬 + 캐시
|
|
25
|
+
jobs:
|
|
26
|
+
lint:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/cache@v4
|
|
30
|
+
with: { path: node_modules, key: deps-${{ hashFiles('yarn.lock') }} }
|
|
31
|
+
- run: yarn lint
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/cache@v4
|
|
37
|
+
with: { path: node_modules, key: deps-${{ hashFiles('yarn.lock') }} }
|
|
38
|
+
- run: yarn test
|
|
39
|
+
|
|
40
|
+
build:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
needs: [lint, test] # lint/test 병렬 후 build
|
|
43
|
+
steps:
|
|
44
|
+
- run: yarn build
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**모노레포:** Turborepo `--filter=[HEAD^1]`, Nx `affected:test`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Speed Up Local Development Server
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Faster feedback loop, improved developer productivity
|
|
5
|
+
tags: dx, dev-server, hmr, startup, watch
|
|
6
|
+
languages: [js, ts, go, python, rust]
|
|
7
|
+
related: [build-incremental, dx-ci-speed]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 로컬 개발 서버 시작 속도 개선
|
|
11
|
+
|
|
12
|
+
개발 서버 시작 시간과 HMR(Hot Module Replacement) 속도를 최적화합니다.
|
|
13
|
+
|
|
14
|
+
**프론트엔드:**
|
|
15
|
+
|
|
16
|
+
| 도구 | 팁 |
|
|
17
|
+
|------|-----|
|
|
18
|
+
| **Vite** | 이미 빠름. `server.warmup` 활성화, `optimizeDeps.include` 프리번들링 |
|
|
19
|
+
| **webpack** | Vite/Turbopack으로 마이그레이션 고려 |
|
|
20
|
+
| **Next.js** | Turbopack (`next dev --turbo`) |
|
|
21
|
+
|
|
22
|
+
**백엔드:**
|
|
23
|
+
|
|
24
|
+
| 언어 | 도구 | 설정 |
|
|
25
|
+
|------|------|------|
|
|
26
|
+
| **Node.js** | `tsx --watch` | 네이티브 ESM, 즉시 시작 |
|
|
27
|
+
| **Go** | `air` | `.air.toml` 설정 |
|
|
28
|
+
| **Python** | `uvicorn --reload` | FastAPI 기본 |
|
|
29
|
+
| **Rust** | `cargo-watch` | `cargo watch -x run` |
|
|
30
|
+
|
|
31
|
+
**공통 개선:**
|
|
32
|
+
|
|
33
|
+
- TypeScript: `tsconfig.json`에서 `skipLibCheck: true` (개발 시)
|
|
34
|
+
- 불필요 플러그인 비활성화 (개발 시 린팅 플러그인 분리)
|
|
35
|
+
- `.gitignore`/`watchignore`에 빌드 출력 디렉토리 추가
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Optimize Linter and Formatter Configuration
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Consistent code style, faster feedback loop
|
|
5
|
+
tags: dx, lint, format, eslint, prettier, biome, ruff
|
|
6
|
+
languages: all
|
|
7
|
+
related: [dx-type-safety, code-complexity]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 린터/포매터 최적 설정
|
|
11
|
+
|
|
12
|
+
프로젝트에 맞는 린터/포매터를 설정하여 일관된 코드 스타일과 빠른 피드백을 보장합니다.
|
|
13
|
+
|
|
14
|
+
**언어별 권장 도구 (2026):**
|
|
15
|
+
|
|
16
|
+
| 언어 | 린터 | 포매터 | 비고 |
|
|
17
|
+
|------|------|--------|------|
|
|
18
|
+
| **JS/TS** | ESLint 9 (flat config) | Prettier 또는 Biome | Biome = lint+format 올인원 |
|
|
19
|
+
| **Python** | Ruff | Ruff (format) | flake8+isort+black 100x 빠른 대체 |
|
|
20
|
+
| **Go** | go vet + staticcheck | gofmt (내장) | |
|
|
21
|
+
| **Rust** | clippy | rustfmt (내장) | |
|
|
22
|
+
| **Java** | SpotBugs / Error Prone | google-java-format | |
|
|
23
|
+
|
|
24
|
+
**빠른 피드백을 위한 설정:**
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
// lint-staged (Git 커밋 시 변경 파일만)
|
|
28
|
+
{
|
|
29
|
+
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
|
|
30
|
+
"*.py": ["ruff check --fix", "ruff format"],
|
|
31
|
+
"*.go": ["gofmt -w"],
|
|
32
|
+
"*.rs": ["rustfmt"]
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**원칙:** 전체 프로젝트 린트는 CI에서, 로컬은 변경 파일만 (lint-staged).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Ensure Test Coverage on Critical Paths
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Confidence in refactoring, catches regressions
|
|
5
|
+
tags: dx, test, coverage, critical-path
|
|
6
|
+
languages: all
|
|
7
|
+
related: [code-error-handling, dx-ci-speed]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 핵심 로직 테스트 커버리지 확보
|
|
11
|
+
|
|
12
|
+
100% 커버리지보다 핵심 비즈니스 로직의 높은 커버리지가 중요합니다.
|
|
13
|
+
|
|
14
|
+
**우선순위:**
|
|
15
|
+
|
|
16
|
+
| 우선순위 | 대상 | 이유 |
|
|
17
|
+
|---------|------|------|
|
|
18
|
+
| **1** | 비즈니스 로직/도메인 | 변경 빈도 높음, 버그 영향 큼 |
|
|
19
|
+
| **2** | 데이터 변환/파싱 | 엣지 케이스 많음 |
|
|
20
|
+
| **3** | API 엔드포인트 | 외부 계약 |
|
|
21
|
+
| **4** | 에러 처리 경로 | 간과하기 쉬움 |
|
|
22
|
+
| LOW | UI 컴포넌트 렌더링 | 자주 변경, ROI 낮음 |
|
|
23
|
+
| LOW | 외부 서비스 호출 | Mock 필요, 깨지기 쉬움 |
|
|
24
|
+
|
|
25
|
+
**테스트 도구 (2026):**
|
|
26
|
+
|
|
27
|
+
| 언어 | 도구 | 특징 |
|
|
28
|
+
|------|------|------|
|
|
29
|
+
| **JS/TS** | Vitest | Vite 통합, ESM 네이티브, 빠름 |
|
|
30
|
+
| **Python** | pytest | 풍부한 에코시스템 |
|
|
31
|
+
| **Go** | testing (내장) | `go test -cover` |
|
|
32
|
+
| **Rust** | cargo test (내장) | `cargo tarpaulin` (커버리지) |
|
|
33
|
+
|
|
34
|
+
**목표:** 핵심 로직 80%+, 전체 60%+ (프로젝트 성격에 따라 조정).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Maximize Type System Usage
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Catches bugs at compile time, better IDE support
|
|
5
|
+
tags: dx, type, safety, strict, generics
|
|
6
|
+
languages: [ts, go, rust, java, csharp]
|
|
7
|
+
related: [code-error-handling, code-naming]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 타입 시스템 최대 활용
|
|
11
|
+
|
|
12
|
+
언어의 타입 시스템을 최대한 활용하여 런타임 에러를 컴파일 타임에 잡습니다.
|
|
13
|
+
|
|
14
|
+
**언어별 strict 설정:**
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
// TypeScript - tsconfig.json
|
|
18
|
+
{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true } }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```toml
|
|
22
|
+
# Rust - Clippy strict
|
|
23
|
+
[lints.clippy]
|
|
24
|
+
pedantic = "warn"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
# Python - mypy strict
|
|
29
|
+
[tool.mypy]
|
|
30
|
+
strict = true
|
|
31
|
+
disallow_any_generics = true
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```go
|
|
35
|
+
// Go - go vet + staticcheck
|
|
36
|
+
// go vet ./...
|
|
37
|
+
// staticcheck ./...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**패턴:**
|
|
41
|
+
|
|
42
|
+
| 패턴 | 효과 | 언어 |
|
|
43
|
+
|------|------|------|
|
|
44
|
+
| **Discriminated union** | 상태별 안전한 분기 | TS, Rust (enum), Python (Literal) |
|
|
45
|
+
| **Branded type** | 같은 원시형 혼동 방지 | TS (`type UserId = string & { __brand: 'UserId' }`) |
|
|
46
|
+
| **Exhaustive check** | switch에서 누락 분기 감지 | TS (`never`), Rust (match), Go (exhaustive) |
|
|
47
|
+
| **Generic constraint** | 타입 파라미터 제한 | 모든 정적 타입 언어 |
|
|
48
|
+
|
|
49
|
+
**원칙:** `any`/`object`/`interface{}` 사용 최소화. 가능한 가장 구체적인 타입 사용.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Batch Queries to Eliminate N+1
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: 100x fewer queries, 10x faster response
|
|
5
|
+
tags: io, database, n+1, batch, query
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-parallel, io-cache-layer]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## N+1 쿼리 제거
|
|
11
|
+
|
|
12
|
+
목록 조회 후 각 항목마다 추가 쿼리를 실행하는 N+1 패턴을 배치/조인으로 전환합니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (N+1):**
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# 100명 유저 = 101 쿼리
|
|
18
|
+
users = db.query("SELECT * FROM users")
|
|
19
|
+
for user in users:
|
|
20
|
+
orders = db.query(f"SELECT * FROM orders WHERE user_id = {user.id}")
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Prisma N+1
|
|
25
|
+
const users = await prisma.user.findMany()
|
|
26
|
+
for (const user of users) {
|
|
27
|
+
const orders = await prisma.order.findMany({ where: { userId: user.id } })
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**✅ 올바른 예시 (배치/조인):**
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
# 2 쿼리
|
|
35
|
+
users = db.query("SELECT * FROM users")
|
|
36
|
+
user_ids = [u.id for u in users]
|
|
37
|
+
orders = db.query("SELECT * FROM orders WHERE user_id = ANY($1)", user_ids)
|
|
38
|
+
|
|
39
|
+
# SQLAlchemy - eager loading
|
|
40
|
+
users = session.query(User).options(selectinload(User.orders)).all()
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// Prisma - include
|
|
45
|
+
const users = await prisma.user.findMany({
|
|
46
|
+
include: { orders: true }
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```go
|
|
51
|
+
// GORM - Preload
|
|
52
|
+
var users []User
|
|
53
|
+
db.Preload("Orders").Find(&users)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
# ActiveRecord - includes
|
|
58
|
+
users = User.includes(:orders).all
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```java
|
|
62
|
+
// JPA - EntityGraph
|
|
63
|
+
@EntityGraph(attributePaths = {"orders"})
|
|
64
|
+
List<User> findAll();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**감지 방법:** 쿼리 로그에서 반복되는 유사 쿼리 패턴 확인. ORM 쿼리 카운터 활용.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Add Cache Layer for Repeated Reads
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: 10-100x latency reduction for cached data
|
|
5
|
+
tags: io, cache, lru, ttl, redis, in-memory
|
|
6
|
+
languages: all
|
|
7
|
+
related: [io-batch-queries, memory-bounded-cache]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 반복 읽기에 캐시 레이어 추가
|
|
11
|
+
|
|
12
|
+
동일 데이터를 반복 조회하는 경우 인메모리/외부 캐시를 추가하여 DB/API 부하를 줄입니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (매번 DB 조회):**
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
def get_user(user_id: str) -> User:
|
|
18
|
+
return db.query("SELECT * FROM users WHERE id = $1", user_id)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**✅ 올바른 예시 (캐시 레이어):**
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# Python (functools.lru_cache)
|
|
25
|
+
from functools import lru_cache
|
|
26
|
+
|
|
27
|
+
@lru_cache(maxsize=1000)
|
|
28
|
+
def get_config(key: str) -> str:
|
|
29
|
+
return db.query("SELECT value FROM config WHERE key = $1", key)
|
|
30
|
+
|
|
31
|
+
# TTL 있는 캐시 (cachetools)
|
|
32
|
+
from cachetools import TTLCache
|
|
33
|
+
cache = TTLCache(maxsize=1000, ttl=300) # 5분
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Node.js (lru-cache)
|
|
38
|
+
import { LRUCache } from 'lru-cache'
|
|
39
|
+
const cache = new LRUCache<string, User>({ max: 1000, ttl: 5 * 60 * 1000 })
|
|
40
|
+
|
|
41
|
+
async function getUser(id: string): Promise<User> {
|
|
42
|
+
const cached = cache.get(id)
|
|
43
|
+
if (cached) return cached
|
|
44
|
+
const user = await db.user.findUnique({ where: { id } })
|
|
45
|
+
if (user) cache.set(id, user)
|
|
46
|
+
return user
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```go
|
|
51
|
+
// Go (groupcache / ristretto)
|
|
52
|
+
import "github.com/dgraph-io/ristretto"
|
|
53
|
+
cache, _ := ristretto.NewCache(&ristretto.Config{
|
|
54
|
+
NumCounters: 1e7, MaxCost: 1 << 30, BufferItems: 64,
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```rust
|
|
59
|
+
// Rust (moka)
|
|
60
|
+
use moka::future::Cache;
|
|
61
|
+
let cache: Cache<String, User> = Cache::builder()
|
|
62
|
+
.max_capacity(1000)
|
|
63
|
+
.time_to_live(Duration::from_secs(300))
|
|
64
|
+
.build();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**캐시 전략:** 읽기 빈도 높고, 쓰기 빈도 낮은 데이터에 적용. TTL로 신선도 보장.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Reuse Connections with Pooling
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Eliminates connection overhead, 5-20x throughput
|
|
5
|
+
tags: io, connection, pool, keep-alive, reuse
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-pool, memory-pool-reuse]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 커넥션 풀/재사용
|
|
11
|
+
|
|
12
|
+
매 요청마다 새 커넥션을 생성하지 않고 풀에서 재사용합니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (매번 새 커넥션):**
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
def get_user(user_id):
|
|
18
|
+
conn = psycopg2.connect(DSN) # 매번 TCP 핸드셰이크 + TLS + 인증
|
|
19
|
+
cursor = conn.cursor()
|
|
20
|
+
cursor.execute("SELECT ...", (user_id,))
|
|
21
|
+
result = cursor.fetchone()
|
|
22
|
+
conn.close()
|
|
23
|
+
return result
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**✅ 올바른 예시 (커넥션 풀):**
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
# Python (SQLAlchemy)
|
|
30
|
+
engine = create_engine(DSN, pool_size=10, max_overflow=20, pool_recycle=3600)
|
|
31
|
+
|
|
32
|
+
# Python (asyncpg)
|
|
33
|
+
pool = await asyncpg.create_pool(DSN, min_size=5, max_size=20)
|
|
34
|
+
async with pool.acquire() as conn:
|
|
35
|
+
result = await conn.fetchrow("SELECT ...", user_id)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// Prisma (자동 풀링)
|
|
40
|
+
// datasource db { url = "..." } → connection_limit 설정
|
|
41
|
+
// schema.prisma: url = "...?connection_limit=10"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```go
|
|
45
|
+
// Go (database/sql - 내장 풀)
|
|
46
|
+
db, _ := sql.Open("postgres", dsn)
|
|
47
|
+
db.SetMaxOpenConns(25)
|
|
48
|
+
db.SetMaxIdleConns(10)
|
|
49
|
+
db.SetConnMaxLifetime(5 * time.Minute)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```rust
|
|
53
|
+
// Rust (deadpool-postgres)
|
|
54
|
+
let pool = Pool::builder(manager).max_size(16).build().unwrap();
|
|
55
|
+
let client = pool.get().await?;
|
|
56
|
+
let rows = client.query("SELECT ...", &[&user_id]).await?;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```java
|
|
60
|
+
// Java (HikariCP)
|
|
61
|
+
HikariConfig config = new HikariConfig();
|
|
62
|
+
config.setMaximumPoolSize(10);
|
|
63
|
+
config.setMinimumIdle(5);
|
|
64
|
+
config.setConnectionTimeout(30000);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**HTTP 커넥션 재사용:** `Keep-Alive` 헤더, HTTP/2 멀티플렉싱, HTTP 클라이언트 인스턴스 재사용.
|