- vừa được xem lúc

Golang Context Deadline và Timeout Là Gì.

0 0 35

Người đăng: Open Dev

Theo Viblo Asia

Tại sao phải dùng context dealine

Một vài trường hợp là khi lập trình các service cần đến deadline mà cần sử dụng phổ biến nhất:

  • Connect đến các loại database như Mysql, Oracle,... Không thể để connect kết nối một thời gian dài, chúng ta cần set đến time để cancel connect .
  • Trường hợp khác đó là connect đến các service bên ngoài thông qua http. Chúng ta cần set time out cũng như deadline cho nó.

Khái niệm

  • Context Dealine được hiểu cách đơn giản là một tính hiệu để huỷ các sự kiện search, query đến cơ sở dữ liệu hoặc các dịch vụ bên ngoài. Ở đây mình sẽ giải thích với deadline còn timeout thực chất cũng là một deadline mà thôi.
  • Khi user nhập /search?q=golang&timeout=1s param timeout 1s là muốn chỉ định server là cancel request sau 1s.

Demo

  • Đầu tiên bạn viết một function dùng để call service bên ngoài, và tốn 1second để xử lý và trả về kết quả.
func callExternalService(w http.ResponseWriter, r *http.Request) { time.Sleep(1 * time.Second) fmt.Println("response hello")
}
  • Tiếp theo bạn viết func call service bên ngoài và set timeout là 2second cho việc call đó.
func execCall() error { client := &http.Client{} req, err := http.NewRequest(http.MethodGet, "http://localhost:8080", nil) if err != nil { return err } ctx, cancel := context.WithTimeout(req.Context(), 2*time.Second) defer cancel() req = req.WithContext(ctx) _, err = client.Do(req) return err
}

Ở đây, khi execCall thực thi thì sẽ set timeout cho nó là là 2second, nghĩa là nếu waiting response quá 2second thì sẽ không nhận được kết quả là trả về error luôn.

  • Tiếp đến là hàm main.
func main() { go func() { http.HandleFunc("/", callExternalService) if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } }() time.Sleep(1 * time.Second) // wait for server to run // call server err := execCall() if errors.Is(err, context.DeadlineExceeded) { log.Println("ContextDeadlineExceeded: true") } if os.IsTimeout(err) { log.Println("IsTimeoutError: true") } if err != nil { log.Fatal(err) }
}

Sau khi run go run main.go sẽ nhận được kết quả vì callExternalService chỉ thực thi tốn 1second còn timeout2second

response hello

TimeOut Bây giờ chúng ta sẽ thay đổi func callExternalService và set timout là 3second

func callExternalService(w http.ResponseWriter, r *http.Request) { time.Sleep(3 * time.Second) fmt.Println("response hello")
}

=> điều này đồng nhiều là timeout của chúng ta sẽ được thực hiện vì hiện tại chỉ có 2second. Kết quả:

ContextDeadlineExceeded: true

IsTimeoutError: true

Get "http://localhost:8080": context deadline exceeded

Full Code

Bình luận

Bài viết tương tự

- vừa được xem lúc

gRPC - Nó là gì và có nên sử dụng hay không?

Nhân một ngày rảnh rỗi, mình ngồi đọc lại RPC cũng như gRPC viết lại để nhớ lâu hơn. Vấn đề là gì và tại sao cần nó .

0 0 132

- vừa được xem lúc

Embedded Template in Go

Getting Start. Part of developing a web application usually revolves around working with HTML as user interface.

0 0 57

- vừa được xem lúc

Tạo Resful API đơn giản với Echo framework và MySQL

1. Giới thiệu.

0 0 61

- vừa được xem lúc

Sử dụng goquery trong golang để crawler thông tin các website Việt Nam bị deface trên mirror-h.org

. Trong bài viết này, mình sẽ cùng mọi người khám phá một package thu thập dữ liệu có tên là goquery của golang. Mục tiêu chính của chương trình crawler này sẽ là lấy thông tin các website Việt Nam bị deface (là tấn công, phá hoại website, làm thay đổi giao diện hiển thị của một trang web, khi người

0 0 237

- vừa được xem lúc

Tạo ứng dụng craw dữ liệu bing với Golang, Mysql driver

Chào mọi người . Lâu lâu ta lại gặp nhau 1 lần, để tiếp tục series chia sẻ kiến thức về tech, hôm nay mình sẽ tìm hiểu và chia sẻ về 1 ngôn ngữ đang khá hot trong cộng đồng IT đó là Golang.

0 0 76

- vừa được xem lúc

Golang: Rest api and routing using MUX

Routing with MUX. Let's create a simple CRUD api for a blog site. # All . GET articles/ .

0 0 55