티스토리 뷰
Photo by Paweł Czerwiński on Unsplash
custom 하게 timeout을 설정한 http client를 생성해서 사용하자는 포스팅을 하였다. https://jusths.tistory.com/203
그런데 context를 사용하는 방법도 있다. 이 경우에는 중간에 취소를 할 수 있다는 장점까지 있다.
context timeout
playground: https://play.golang.org/p/X46kgspmjTw
- 여기서 실행은 되지 않는다. 코드만 참고하자
- 실행은 별도로 PC에서 테스트하거나 https://repl.it 사이트에서 테스트하자
1) ctx를 만든다.
- 어떤 context 이건 처음 생성은 context.Background() 이다.
- 그렇게 최초 생성한 context를 다시 context.WithTimeout()에 넣고, timeout 시간을 3초로 하여 ctx를 생성하였다
2) http.Client 에 아무런 Timeout 옵션 없이 생성한다
3) http.NewRequest()를 만들고, 위에서 생성한 client를 이용하여 req.WithContext()로 보낸다.
4) 테스트 서버는 1분동안 sleep 이니, 즉 1분동안 응답이 없으니
4) context 에서 설정한 3초뒤에 timeout이 발생한다.
making request 2021/03/05 08:18:25 Get "http://127.0.0.1:39541": context deadline exceeded |
context의 cancel을 써보자
해보려는 것은
1) 1분 뒤에나 회신을 주는 테스트 서버를 만들고
2) 30초 뒤에 timeout이 걸리는 request를 고루틴을 통해 보낸 다음
3) 3초 뒤에 context를 생성시에 만들어둔 cancel을 사용해 보는 것이다.
아래 예제를 보면 원했던 대로 cancel에 의해서 request가 중지된 것을 알 수 있다.
playground: https://play.golang.org/p/iMaLPzVZgQ7
making request 2021/03/05 09:01:47 cancel reqeust 2021/03/05 09:01:47 Get "http://127.0.0.1:45947": context canceled |
심화 학습 - context의 cancel을 어디다 써먹지?
강아지가 사라졌다. 엄마, 아빠, 누나가 동네에 흩어져서 강아지를 찾기 시작한다.
엄마가 강아지를 찾았다면, 엄마는 아빠와 누나에게 연락을 해서 "강아지 찾기" 미션을 cancel 하고 집으로 오라고 연락해야 한다.
자료를 찾아야하는데 DB가 여러 개다. 각각의 DB서버에 요청을 보냈다.
한 DB 서버에서 찾았다는 회신을 받았다. 나머지 request를 cancel해야 한다.
이럴때에 context의 cancel을 쓰면 된다. 예제를 만들어 보았다.
playground: https://play.golang.org/p/Z74U4SccotQ
테스트 서버의 핸들러를 살짝 바꾸었다.
랜덤하게 delay가 발생한 다음 response를 해준다.
1) context를 생성하는데 cancel이 가능하도록 해둠
- context는 무전기라고 생각하면 편하다. 앞으로 서버로 보내는 5개의 request에 같은 주파수(?)의 무전기, 즉 같은 context를 넣어서 보낼 것이다.
2) http.Client는 Timeout 설정은 하지 않았다
3) 5개의 고루틴이 생성되는데 각 고루틴은 context와 함께 request가 날아간다
4) 5개의 request에 대하여 server의 handler는 임의의 시간동안 지연이 발생한 다음 response를 할 예정이다
5) 그런데 에러가 없이 response를 받는 고루틴의 경우에 context의 cancel()을 실행하는 것이 보인다 - 이게 제일 중요한 부분이다.
6) 즉, 가장 빨리 response를 정상적으로 받은 고루틴이 이제 더 이상 request를 수행할 필요가 없다고 cancel 명령을 (무전기를 통해서) 보내는 것이다.
[참고] sync.WaitGroup 사용법에 대해서는 생략함
making request 2021/03/05 09:36:35 delay: 2s seconds 2021/03/05 09:36:35 delay: 8s seconds 2021/03/05 09:36:35 delay: 8s seconds 2021/03/05 09:36:35 delay: 10s seconds --response: hello http client! 2021/03/05 09:36:36 err: Get "http://127.0.0.1:41509": context canceled 2021/03/05 09:36:36 delay: 2s seconds 2021/03/05 09:36:36 err: Get "http://127.0.0.1:41509": context canceled 2021/03/05 09:36:36 err: Get "http://127.0.0.1:41509": context canceled 2021/03/05 09:36:36 err: Get "http://127.0.0.1:41509": context canceled --finish the program |
끝
'golang' 카테고리의 다른 글
SOLID in GO - Single Responsibility Principle (0) | 2021.03.31 |
---|---|
Go HTTP server를 GitHub Action을 이용해 Heroku로 deploy 해보자 (0) | 2021.03.29 |
Golang - http.Client에는 Timeout이 들어가야 한다. (0) | 2021.03.04 |
코로나 바이러스 확진자 동향 3주간 비교 - Heroku로 서비스하기 (0) | 2021.03.03 |
코로나 바이러스 확진자 동향 3주간 비교 - 차트 만들기 (0) | 2021.03.03 |
- Total
- Today
- Yesterday
- github
- ChatGPT
- postgres
- agile
- golang
- 영화
- notion
- intellij
- websocket
- Shortcut
- 인텔리제이
- pool
- solid
- 제이펍
- Gin
- 독서후기
- 독서
- API
- strange
- JIRA
- OpenAI
- folklore
- go
- bun
- Bug
- 잡학툰
- 2023
- 노션
- 클린 애자일
- 체호프
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |