[Go 공식문서 한국어 정리] ⓮37. Go 동시성 패턴: Context
Go 동시성 패턴: Context
https://go.dev/blog/context
Go 서버에서 각 요청은 도도 고루틴(Goroutine)에서 처리됩니다. 이때 요청은 자신만의 값(예: 사용자 ID, 인증 토큰, 데드라인)과 함께 작동하는 다른 고루틴을 시작하는데, 요청이 취소되거나 시간이 초과되면 관련 고루틴이 모두 정지되어야 자원을 재활용할 수 있습니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
① 서론
Go 의 context 패키지는 Google 에서 개발해 Go 1.7에 스킨더드 라이브러리로 포함되었습니다. 이것은 요청의 범위(request-scoped)값과 취소 신호, 데드라인을 API 경계를 넘어 모든 고루틴에게 전달하는 공통 인터페이스를 제공합니다.
② 핵심 개념
1. Context 인터페이스: Done() 채널로 취소 신호를, Err()로 원인을, Deadline()로 마감시간을, Value()로 요청범위 값을 제공합니다.
2. 여러 고루틴에 동시에 안전하게 사용될 수 있습니다.
3. Context는 쉴드된 트리구조이며, 부모가 취소되면 자식도 취소됩니다.
4. Background()는 루트 Context이며 영원히 취소되지 않습니다.
③ 주요 내용 상세
Context 생성 함수
- context.Background(): 비어 있는 루트 Context를 반환합니다.
- context.WithCancel(parent): 부모를 복사하여 수동 취소가 가능한 Context와 cancel 함수를 반환합니다.
- context.WithTimeout(parent, timeout): 제한 시간이 지나면 자동으로 취소되는 Context를 반환합니다.
- context.WithValue(parent, key, val): 요청범위 값을 저장하는 Context를 반환합니다.
실전 예제: Google Web Search
HTTP 서버가 /search?q=golang&timeout=1s 요청을 처리하는 예제입니다. handleSearch에서 req.FormValue("timeout")로 제한 시간을 파싱해 context.WithTimeout을 생성하거나, 없으면 context.WithCancel를 사용합니다. defer cancel()로 핸들러 종료 시 자동 취소되도록 합니다.
userip 패키지
사용자 IP를 Context에 저장하는 예제입니다. 내부 키 타입(key int)을 정의해 외부 패키지와 충돌을 방지하고, context.WithValue/Value로 강형 타입으로 저장/조회합니다.
httpDo 합수
새 고루틴에서 HTTP 요청을 실행하고, select문으로 ctx.Done()과 응답 수신을 대기합니다. ctx.Done()가 먼저 닫히면 요청을 취소하고 ctx.Err()를 반환합니다.
④ 실전 활용
- 운영 환경에서 HTTP 서버의 요청 핸들러는 context.Background()로 시작해 제한 시간이나 취소 신호를 전달합니다.
- 데이터베이스에서 조회하는 함수에 Context를 매개변수로 전달해 조회가 지연될 때 취소할 수 있습니다.
- gRPC, database/sql, net/http등 대부분 라이브러리도 Context를 지원합니다.
- Context의 값은 동시에 안전해야 하므로 락을 포함한 값을 사용하지 마세요.
⑤ 정리
Context는 Go 서버의 요청 범위 데이터와 취소, 타임아웃을 표준화한 공통 인터페이스입니다. 함수의 첫 번째 매개변수로 Context를 전달하는 관습을 급히 기른시면 확장성있는 서비스를 쉽게 개발할 수 있습니다.
#Go #Golang #Context #동시성 #취소 #타임아웃 #고루틴 #공식문서

오뉴노노 님의 최근 댓글
ㅋㅋㅋㅋㅋ 2019 01.14 잘 읽었습니다 2018 12.30 포인트가 없어서 아직 시작을 못하고있는데요! 글은 잘 읽었습니다! 포인트 쌓고 도전할거에요 2018 12.30