Skip to content

Commit

Permalink
update section55
Browse files Browse the repository at this point in the history
  • Loading branch information
gleaming9 committed Nov 13, 2024
1 parent c76d883 commit 3b53ca6
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 7 deletions.
2 changes: 1 addition & 1 deletion _chapter14/section54/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package section54

import (
"fmt"
Expand Down
50 changes: 48 additions & 2 deletions _chapter14/section55/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
package section55
package main

func main() {
import (
"context"
"fmt"
"golang.org/x/sync/errgroup"
"log"
"net/http"
)

func run(ctx context.Context) error {
s := &http.Server{
Addr: ":18080",
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}),
}
//errgroup.WithContext(ctx)는 오류 그룹과 새로운 context를 반환합니다.
//이 context는 서버가 종료되거나 다른 고루틴에서 오류가 발생하면 자동으로 취소됩니다.
eg, ctx := errgroup.WithContext(ctx)

//errgroup의 Go 메서드를 사용하여 서버를 실행하는 고루틴을 생성합니다.
//이 고루틴은 s.ListenAndServe()를 호출하여 서버를 시작합니다.
eg.Go(func() error {
if err := s.ListenAndServe(); err != nil &&
err != http.ErrServerClosed {
log.Printf("failed to close: %+v", err)
return err
}
return nil
})
/*
ctx.Done() 채널을 대기하여 context가 취소될 때까지 기다립니다.
ctx.Done()이 반환되면 서버 종료를 시작합니다.
s.Shutdown(context.Background())를 호출하여 안전하게 서버를 종료하며,
Shutdown은 기존의 모든 연결을 안전하게 종료합니다.
*/
<-ctx.Done()
if err := s.Shutdown(context.Background()); err != nil {
log.Printf("failed to shutdown: %+v", err)
}
//모든 고루틴이 종료될 때까지 기다립니다.
//만약 어떤 고루틴에서 오류가 발생했다면 그 오류를 반환합니다.
return eg.Wait()
}

func main() {
if err := run(context.Background()); err != nil {
log.Printf("failed to terminate server: %v", err)
}
}
43 changes: 39 additions & 4 deletions _chapter14/section55/main_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
package section55
package main

import "testing"
import (
"context"
"fmt"
"golang.org/x/sync/errgroup"
"io"
"net/http"
"testing"
)

func TestMain(m *testing.M) {
go main()
func TestRun(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
eg, ctx := errgroup.WithContext(ctx)
eg.Go(func() error {
return run(ctx)
})

in := "message"
rsp, err := http.Get("http://localhost:18080/" + in)
if err != nil {
t.Errorf("failed to get: %+v", err)
}
defer rsp.Body.Close()

got, err := io.ReadAll(rsp.Body)
if err != nil {
t.Fatalf("failed to read body: %v", err)
}

// HTTP 서버의 반환값을 검증합니다.
want := fmt.Sprintf("Hello, %s!", in)
if string(got) != want {
t.Errorf("want %q, but got %q", want, got)
}

// run 함수를 종료합니다.
cancel()
if err := eg.Wait(); err != nil {
t.Fatal(err)
}
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module go_todo_app

go 1.23.1

require golang.org/x/sync v0.9.0 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=

0 comments on commit 3b53ca6

Please sign in to comment.