yoongrammer

[Go] context 알아보기 본문

언어/Go 언어

[Go] context 알아보기

yoongrammer 2020. 12. 13. 13:24
728x90

목차

    [Go] context 알아보기


    context패키지는 API 및 프로세스 간에 데드라인(deadline) 취소 시그널, 값 등을 전달하기 위해서 사용합니다.

     

    context를 사용하면 작업을 취소하거나 중간에 중지할 수 있습니다.

    취소가 필요한 이유


    작업 취소 시, 불필요한 작업을 수행하지 않고 빠르게 취소할 수 있다면 애플리케이션 성능에 큰 도움이 될 것입니다.

     

    데이터베이스를 호출하여 쿼리된 데이터를 클라이언트에 반환하는 서버가 있다고 생각해보겠습니다.

    문제가 없다면 아래와 같이 동작할 것입니다.

    Server가 요청을 받아 DB에 query를 전달하기 전에 클라이언트가 요청을 취소를 한다면 아래와 같이 동작할 것입니다.

     

    클라이언트가 중간에 취소했음에도 불구하고 Server는 DB에 query를 전달하고 data를 받아오는 불필요한 작업을 수행하게 됩니다.

     

    위와 동일한 상황에서 context를 사용하여 취소를 한다면 아래 그림과 같이 서버는 불필요한 작업을 수행하지 않고 바로 취소할 수 있습니다.

    이와 같이 context를 사용하면 요청에 대한 모든 작업들을 빠르게 취소할 수 있게 됩니다.

    Context 패키지


    Context에 WithCancel, WithDeadline, WithTimeou함수는 부모 context를 사용하여 파생된 자식contextCancelFunc 함수를 생성합니다.

     

    CancelFunc 함수를 호출하면 파생된 자식 context들을 취소하고 관련된 타이머를 중지합니다.

    CancelFunc 함수를 호출하지 않는다면 부모 context가 취소되거나 타이머가 작동될 때까지 파생된 자식 context들은 남아있게 됩니다.

     

    context를 사용하는 프로그램은 패키지간에 인터페이스를 일관성 있게 유지하고 정적 분석 도구가 context 전파를 확인할 수 있도록 다음 규칙을 따라야 합니다.

     

    1. context를 사용하기 위해선 구조체 안에 context를 저장하지 말고 context를 필요로 하는 함수에 아래 예처럼 명시적으로 전달해야 합니다.

    func DoSomething (ctx context.Context, arg Arg) error { 
    	// ... use ctx ... 
    }

    2. nil을 context 파라미터로 전달하면 안 되고 사용할 context가 확실하지 않은 경우 context.TODO를 전달합니다.

    DoSomething(nil, arg) // (X)
    
    DoSomething(context.TODO(), arg) // (O)

    Context type


    context type은 4개의 method로 구성된 interface입니다.

    type Context interface {
        // Done returns a channel that is closed when this Context is canceled
        // or times out.
        Done() <-chan struct{}
    
        // Err indicates why this context was canceled, after the Done channel
        // is closed.
        Err() error
    
        // Deadline returns the time when this Context will be canceled, if any.
        Deadline() (deadline time.Time, ok bool)
    
        // Value returns the value associated with key or nil if none.
        Value(key interface{}) interface{}
    }

    1. Done()

    Done method는 context에 취소나 timeout 이벤트가 발생하면 닫히는 채널을 반환합니다.

    Done method를 통해 context에 취소나 timeout 이벤트가 발생했는지 알 수 있습니다.

     

     

    2. Err()

    Err method는 Done 채널이 닫힌 후에 context가 취소된 이유를 나타내는 오류를 반환합니다.

    Done이 닫혀있지 않다면 nil을 반환합니다.

     

    3. Deadline()

    Deadline method는 context가 취소되는 시간(deadline)을 반환합니다. 취소 시간이 정해져 있지 않다면 ok 값으로는 false를 반환합니다.

     

    4. Value()

    Value method는 key와 관련된 값을 반환하거나 없는 경우 nil을 반환합니다.

    WithValue 함수를 사용하여 context에 key와 관련된 값을 넣을 수 있습니다.

    Empty context


    Empty contextvaluedeadline이 없는 빈 context입니다.

    Empty context는 취소할 수 없습니다.

     

    Background(), TODO() 함수는 empty context를 생성합니다.

    func Background

    func Background() Context

    Background는 main, init 등 최상의 요청을 받는 곳에서 사용됩니다.

    func TODO

    func TODO() Context

    TODO는 사용할 context가 명확하지 않을 경우에 사용합니다.

    Derived contexts


    context 패키지는 기존 값에서 새 context값을 파생하는 함수를 제공합니다.

    이러한 값은 트리를 형성합니다. context가 취소되면 파생된 모든 context도 취소됩니다.

     

    Background함수에 의해 생성된 empty context은 모든 context 트리의 루트입니다.

    루트 트리는 취소되지 않습니다.

     

    WithCancel, WithDeadline, WithTimeout 함수는 부모 context보다 빨리 취소할 수 있는 자식 context를 생성합니다.

    func WithCancel

    func WithCancel (parent Context) (ctx Context, cancel CancelFunc)

    WithCancel 함수는 부모 context로부터 파생된 자식 context와 cancel 함수를 반환합니다.

    반환된 context의 Done 채널은 cancel함수가 호출되거나 부모 context의 Done 채널이 닫힐때 닫힙니다.

    func WithDeadline

    func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)

    WithDeadline 함수는 부모 context로부터 파생된 자식 context와 cancel함수를 반환합니다.

    반환된 context의 Done 채널은 deadline(d)이 만료되거나 cancel함수가 호출될 때 또는 부모 context의 Done 채널이 닫힐 때 닫힙니다.

    func WithTimeout

    func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

    WithTimeout 함수는 내부에서 WithDeadline(parent, time.Now().Add(timeout)) 함수를 호출합니다.

    반환된 context의 Done 채널은 timeout 시간이 지나거나 cancel함수가 호출될 때 또는 부모 context의 Done 채널이 닫힐 때 닫힙니다.

    type CancelFunc

    type CancelFunc func()

    CancelFunc은 작업을 취소할 때 사용합니다.

    728x90

    '언어 > Go 언어' 카테고리의 다른 글

    [Go] JSON 패키지 알아보기  (0) 2021.01.02
    [Go] context 사용하기  (0) 2020.12.14
    [Go] Modules 사용하기  (0) 2020.12.07
    [Go] Modules 알아보기  (0) 2020.12.06
    [Go] Handle, Handler , HandleFunc 이해  (0) 2020.11.26
    Comments