TIL: Go에서 다른 서버를 수신하는 방법(select 사용)
9704 단어 todayilearnedgoselect
select
문을 올바르게 사용하는 것이었습니다.이것이 시작점입니다. 리팩토링 시작 시 존재했던 "인위적"선택을 가장 잘 강조하기 위해 대부분의 코드를 생략하고 있습니다.
func Start(/* options here*/) error {
errChan := make(chan error)
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
errChan <- fmt.Errorf("%s", <-c)
}()
// [...]
go startHTTPSrv(errChan)
// [...]
go startGRPCSrv(errChan)
// [...]
return <-errChan
}
func startHTTPSrv(errChan chan<-error) { // the param list is simplified to focus only on the err chan
errChan <- http.ListenAndServe(/* http.ListenAndServe params */)
}
func startGRPCSrv(errChan chan<-error) { // the param list is simplified to focus only on the err chan
errChan <- gRPCServer.Serve(/* gRPCServer.Serve params */)
}
동일한
errChan
가 모든 곳에서 사용되기 때문에 HTTP 서버, GRPC 또는 SIGINT/SIGTERM 리스너 등 오류를 반환하는 모든 고루틴은 Start
func를 종료합니다.이것은 실제로
select
문의 동작입니다. 이것이 내가 그것을 변형하기 시작한 이유이며 이것이 지금의 모습입니다.func Start(o *Opts) error {
select {
case err := <-startHTTPSrv(newSrvData(o.HTTPAddr)):
return err
case err := <-startGRPCSrv(newSrvData(o.GRPCAddr)):
return err
case err := <-handleSigTerm():
return err
}
}
func startHTTPSrv(/* params */) <-chan error{ // the param list is simplified to focus only on the err chan
// [...]
errChan := make(chan error)
go func() {
errChan <- http.ListenAndServe(/* http.ListenAndServe params */)
}()
return errChan
}
func startGRPCSrv((/* params */) <-chan error { // the param list is simplified to focus only on the err chan
// [...]
errChan := make(chan error)
go func() {
// [...]
errChan <- gRPCServer.Serve(/* gRPCServer.Serve params */)
}()
return errChan
}
func handleSigTerm() <-chan error {
// [...]
errChan := make(chan error)
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
errChan <- fmt.Errorf("%s", <-c)
}()
return errChan
}
이 시점에서
select
문을 사용하면 서로 다른 고루틴이 실행되고 Start
에서 반환하기 위해 첫 번째가 종료될 때까지 대기하는 명확한 구분을 보여줄 수 있습니다.Start
func의 변경 외에도 다른 함수도 select 문 내에서 편안하게 사용할 수 있도록 일반 오류 대신 오류 수신자chan
를 반환하도록 변경되었습니다.이 리팩터링에는 두 가지 긍정적인 측면이 있습니다.
도움이 되었기를 바랍니다. 시간 내어 읽어주셔서 감사합니다!
추신. Here be dragons! 일명 이 TIL에 영감을 준 완전한 변경으로 수행한 커밋에 대한 github 참조입니다.
Reference
이 문제에 관하여(TIL: Go에서 다른 서버를 수신하는 방법(select 사용)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mcaci/til-how-to-listen-to-different-servers-in-go-using-select-566m텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)