context ํจํค์ง๊ฐ ํ๋ ์ญํ
- ์๊ฐ ์ด๊ณผ, ์ทจ์, ์์ฒญ ๋ฒ์ ๋ฐ์ดํฐ ์ ๋ฌ์ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๋๊ตฌ
- ๊ณ ๋ฃจํด ์๋ช ์ฃผ๊ธฐ ์ ์ด
- HTTP ์์ฒญ ์ฒ๋ฆฌ
- ํด๋ผ์ด์ธํธ๊ฐ HTTP ์์ฒญ ์ทจ์ํ์ ์, ๊ทธ์ ๊ด๋ จ๋ DB์กฐํ/API ํธ์ถ ๋ฑ๋ ์ทจ์ํด์ผ ๋ฆฌ์์ค ๋ญ๋น๋ฅผ ํ์ง ์์
- DB์ฟผ๋ฆฌ, ํ์์์ ๊ด๋ฆฌ
- ํน์ ์์ ์ด ๋๋ฌด์ค๋ ๊ฑธ๋ฆฌ๋ฉด ํ์์์ ์ค์ ํด์ ์๋์ผ๋ก ์ข ๋ฃํด์ผ ํจ
context ํจํค์ง ์ฃผ๋ชฉ์
- Context ํ์ ์ ์ ์ํ๊ณ , ์บ์ฌ๋ ์ด์ (cancellation, ์ทจ์) ์ง์
- ๋ฉํ๋ฐ์ดํฐ ์ ์ฅ(gRPC)
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
- Deadline(), Done(), Err(), Value() ๋ก ๊ตฌ์ฑ๋ ์ธํฐํ์ด์ค
์์ฑ
- context.Background()
- ๊ฐ์ฅ ๊ธฐ๋ณธ์ด ๋๋ ๋น Context
- ๋ณดํต main() ํจ์๋ ์ด๊ธฐ ์ค์ ์์ ์ฌ์ฉ
- context.TODO()
- ์์ง ์ด๋ค Context๋ฅผ ์ฌ์ฉํด์ผ ํ ์ง ๋ชจ๋ฅผ ๋ ์์๋ก ์ฌ์ฉ
context๋ฅผ ์ด์ฉํ ์ ์ด
- context.WithCancel(parent)
- cancel()์ ํธ์ถํ๋ฉด ๋ชจ๋ ์์ Context๋ ์ทจ์๋จ
- ์์ Goroutine์ด ๋ถ๋ชจ๊ฐ ์ทจ์๋๋์ง ์ฒดํฌํ ์ ์์
- context.WithTimeout(parent, duration)
- ์ค์ ํ ์๊ฐ(duration)์ด ์ง๋๋ฉด ์๋์ผ๋ก ์ทจ์๋จ
- context.WithDeadline(parent, time)
- ํน์ ์๊ฐ(time)๊น์ง Context๊ฐ ์ ํจ
- context.WithValue(parent, key, value)
- Context์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด ์์ Goroutine์ ์ ๋ฌ
๊ณ ๋ฃจํด์ ๋ถ๋ชจ์์ ๊ด๊ณ๊ฐ ์๋ค๊ณ ์ดํดํ๊ณ ์๋๋ฐ, context๋ฅผ ์ค๋ช ํ ๋๋ Contextํจํค์ง๋ก ๋ถ๋ชจ๊ณ ๋ฃจํด์ ์คํ์ด ๋๋ฌ์ ๋ ์์ ๊ณ ๋ฃจํด์ ์คํ์ ๋ฉ์ถ๋๋ฐ ๋์์ ์ค๋ค๊ณ ์๊ธฐํ๊ณ ์์ด. ๋ด๊ฐ ๊ณ ๋ฃจํด์ ๋ํด ์๋ชป ์ดํดํ๊ณ ์๋๊ฑธ๊น? contextํจํค์ง๋ฅผ ์ค๋ช ํ ๋ ์๊ธฐํ๋ ๋ถ๋ชจ-์์ ๊ณ ๋ฃจํด์ ๋ํด ์ค๋ช ํด์ค
- gorutine์๋ ๋ถ๋ชจ-์์ ๊ด๊ณ๊ฐ ์๋ ๊ฒ์ ๋ง์
- ๋ค๋ง contextํจํค์ง๋ฅผ ์ด์ฉํด์ ๊ณ ๋ฃจํด์ ๋ถ๋ชจ-์์ ๊ด๊ณ๋ฅผ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ค์ ํ๊ณ ์ ์ดํ ์ ์์
๋์ ์ดํด๊ฐ ๋ง์. Go์ Goroutine์ ๋ถ๋ชจ-์์ ๊ด๊ณ๊ฐ ์๊ณ , ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋ผ. ํ์ง๋ง context๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถ๋ชจ Goroutine์ด ์ข ๋ฃ๋ ๋ ์์ Goroutine๋ ์ข ๋ฃํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์์ด. ์ด๊ฑธ โ๋ถ๋ชจ-์์ Goroutine ๊ด๊ณโ๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฑฐ์ผ.
๐น Goroutine์ ๊ธฐ๋ณธ ๋์: ๋ถ๋ชจ-์์ ๊ฐ๋ ์ด ์์ Go์์๋ ํจ์๋ฅผ go ํค์๋๋ฅผ ๋ถ์ฌ ์คํํ๋ฉด ์๋ก์ด Goroutine์ด ์์ฑ๋ผ. ๊ทธ๋ฐ๋ฐ, Goroutine์ ๋ถ๋ชจ Goroutine์ ์๋ช ์ฃผ๊ธฐ์ ๋ ๋ฆฝ์ ์ด์ผ. ์ฆ, ๋ถ๋ชจ Goroutine์ด ์ข ๋ฃ๋๋๋ผ๋ ์์ Goroutine์ด ๊ณ์ ์คํ๋ ์ ์์ด! ์์ : ๋ถ๋ชจ๊ฐ ๋จผ์ ์ข ๋ฃ๋๋ฉด ์์ Goroutine์ ์ด์์์
package main
import (
"fmt"
"time"
)
func worker() {
for i := 0; i < 5; i++ {
fmt.Println("์์
์ค...")
time.Sleep(1 * time.Second)
}
}
func main() {
go worker()
fmt.Println("๋ฉ์ธ ํจ์ ์ข
๋ฃ")
}์คํ ๊ฒฐ๊ณผ (๋ฉ์ธ ํจ์๊ฐ ๋จผ์ ์ข ๋ฃ๋จ)
๋ฉ์ธ ํจ์ ์ข
๋ฃ
(๊ทธ๋ฆฌ๊ณ ํ๋ก๊ทธ๋จ ์ข
๋ฃ๋จ, worker() ์คํ ์ ๋จ!)
- worker() Goroutine์ด ๋ฉ์ธ ํจ์๊ฐ ๋๋๋ ๊ณ์ ์คํ๋ ๊ฒ ๊ฐ์ง๋ง, ๋ฉ์ธ ํจ์๊ฐ ์ข ๋ฃ๋๋ฉด ์ ์ฒด ํ๋ก์ธ์ค๊ฐ ์ข ๋ฃ๋๋ฏ๋ก ์คํ๋์ง ์์.
- ์ฆ, ๊ณ ๋ฃจํด ์์ฒด๋ ๋ถ๋ชจ-์์ ๊ด๊ณ๊ฐ ์์ง๋ง, ๋ฉ์ธ Goroutine(ํ๋ก์ธ์ค์ ์์์ )์ด ๋๋๋ฉด ๋ชจ๋ Goroutine์ด ๊ฐ์ ๋ก ์ข ๋ฃ๋ ์ ์์.
๐น context๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถ๋ชจ Goroutine์ด ์ข ๋ฃ๋ ๋ ์์ Goroutine์ ์์ ํ๊ฒ ๋ฉ์ถ ์ ์์ Goroutine์ด ๋ ๋ฆฝ์ ์ด๊ธฐ ๋๋ฌธ์ ๋ถ๋ชจ Goroutine์ด ์ข ๋ฃ๋๋๋ผ๋ ์์ Goroutine์ด ๊ณ์ ์คํ๋ ์ ์์ด. ์ด๋ context๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถ๋ชจ Goroutine์ ์ข ๋ฃ ์์ ์ ๋ง์ถฐ ์์ Goroutine๋ ์ ๋ฆฌํ ์ ์์ด.
โ Context๋ฅผ ์ฌ์ฉํ ๋ถ๋ชจ-์์ Goroutine ์ ์ด ์์
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done(): // ๋ถ๋ชจ Context๊ฐ ์ทจ์๋๋ฉด ์ฌ๊ธฐ์ ์ข
๋ฃ๋จ
fmt.Println("์์
์ด ์ทจ์๋จ!")
return
default:
fmt.Println("์์
์ํ ์ค...")
time.Sleep(1 * time.Second)
}
}
}
func main() {
// WithCancel์ ์ฌ์ฉํ์ฌ ์ทจ์ ๊ฐ๋ฅํ Context ์์ฑ
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx) // worker Goroutine ์คํ
time.Sleep(3 * time.Second) // 3์ด๊ฐ ์คํ ํ
cancel() // Context ์ทจ์ -> worker Goroutine๋ ์ข
๋ฃ๋จ
time.Sleep(1 * time.Second) // ์ข
๋ฃ ํ์ธ์ ์ํ ๋๊ธฐ
fmt.Println("๋ฉ์ธ ํจ์ ์ข
๋ฃ")
}๐ ์คํ ๊ฒฐ๊ณผ
์์
์ํ ์ค...
์์
์ํ ์ค...
์์
์ํ ์ค...
์์
์ด ์ทจ์๋จ!
๋ฉ์ธ ํจ์ ์ข
๋ฃ
์ด์ ๋ถ๋ชจ Goroutine(main())์ด cancel()์ ํธ์ถํ๋ฉด, worker() Goroutine๋ ์์ ํ๊ฒ ์ข ๋ฃ๋จ!
์ฆ, context๋ฅผ ์ฌ์ฉํด์ ๋ถ๋ชจ Goroutine์ด ์ข ๋ฃ๋ ๋ ์๋์ ์ผ๋ก ์์ Goroutine๋ ์ข ๋ฃํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ ๊ฒ์ด์ผ.
๐น ์ ๋ฆฌ: ์ โ๋ถ๋ชจ-์์ ๊ด๊ณโ๋ผ๊ณ ๋ถ๋ฅผ๊น? โ Goroutine์ ์๋ ๋ถ๋ชจ-์์ ๊ด๊ณ๊ฐ ์์! โ ํ์ง๋ง context๋ฅผ ์ฌ์ฉํ๋ฉด ํน์ Goroutine(๋ถ๋ชจ)์ด ์ทจ์๋์์ ๋, ์ฐ๊ด๋ ๋ค๋ฅธ Goroutine(์์)์ ์ข ๋ฃํ ์ ์์ โ ์ด๋ฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๋ฉด โ๋ ผ๋ฆฌ์ ์ธ ๋ถ๋ชจ-์์ ๊ด๊ณโ ์ฒ๋ผ ๋์ํจ ์ฆ, context๋ Goroutine์ ๊ฐ์ ๋ก ์ข ๋ฃํ๋ ๊ธฐ๋ฅ์ด ์๋๋ผ โ๋ ผ๋ฆฌ์ ์ธ ๋ถ๋ชจ-์์ ๊ด๊ณ๋ฅผ ๋ง๋ค์ด ์ฃผ๋ ๋๊ตฌโ ๋ผ๊ณ ๋ณด๋ฉด ๋ผ. ๐