PHpullh
학습 라이브러리/Go/context 패키지 — 취소 & 타임아웃

GO · 고루틴/채널

context 패키지 — 취소 & 타임아웃

고루틴의 생명주기를 제어하는 context. 취소, 타임아웃, 값 전달에 사용합니다.

고루틴/채널고급contextWithTimeoutWithCancelcancelDone

핵심 설명

고루틴의 생명주기를 제어하는 context. 취소, 타임아웃, 값 전달에 사용합니다.

Go code

package main

import (
	"context"
	"fmt"
	"time"
)

// context를 첫 번째 인자로 받는 것이 Go 관례
func fetchData(ctx context.Context, url string) (string, error) {
	ch := make(chan string, 1)

	go func() {
		// 실제 HTTP 요청 시뮬레이션
		time.Sleep(200 * time.Millisecond)
		ch <- "data from " + url
	}()

	select {
	case data := <-ch:
		return data, nil
	case <-ctx.Done():
		return "", ctx.Err() // context.DeadlineExceeded or Canceled
	}
}

func main() {
	// 타임아웃 컨텍스트
	ctx, cancel := context.WithTimeout(
		context.Background(),
		150*time.Millisecond,
	)
	defer cancel() // 반드시 호출

	result, err := fetchData(ctx, "https://api.example.com")
	if err != nil {
		fmt.Println("실패:", err) // context deadline exceeded
	} else {
		fmt.Println("성공:", result)
	}

	// 취소 컨텍스트 — 수동 취소
	ctx2, cancel2 := context.WithCancel(context.Background())
	go func() {
		time.Sleep(100 * time.Millisecond)
		cancel2() // 취소 신호 전송
	}()

	select {
	case <-ctx2.Done():
		fmt.Println("취소됨:", ctx2.Err())
	case <-time.After(500 * time.Millisecond):
		fmt.Println("타임아웃")
	}

	// context.WithValue — 요청 범위 값 전달
	type keyType string
	ctx3 := context.WithValue(context.Background(),
		keyType("userID"), "user-123")

	if uid, ok := ctx3.Value(keyType("userID")).(string); ok {
		fmt.Println("사용자 ID:", uid)
	}
}

학습 팁

context.WithTimeout 후 반드시 defer cancel()을 호출하세요. 호출하지 않으면 컨텍스트가 완료될 때까지 리소스가 해제되지 않습니다.

주의할 점

context.WithValue의 키는 문자열이 아닌 비공개 타입을 사용하세요. 여러 패키지에서 같은 키를 사용하면 충돌이 생깁니다.

자주 묻는 질문

context 패키지 — 취소 & 타임아웃란 무엇인가요?

고루틴의 생명주기를 제어하는 context . 취소, 타임아웃, 값 전달에 사용합니다.

context 패키지 — 취소 & 타임아웃 학습 시 주의할 점은 무엇인가요?

context.WithValue 의 키는 문자열이 아닌 비공개 타입을 사용하세요. 여러 패키지에서 같은 키를 사용하면 충돌이 생깁니다.