Hủy các thao tác đang thực hiện
Bạn có thể quản lý các thao tác đang thực hiện bằng cách sử dụng
context.Context trong Go. Context là
một kiểu dữ liệu chuẩn trong Go có khả năng báo hiệu khi thao tác tổng thể mà
nó đại diện đã bị hủy và không còn cần thiết nữa. Bằng cách truyền
context.Context qua các lời gọi hàm và dịch vụ trong ứng dụng, các thành
phần đó có thể dừng hoạt động sớm và trả về lỗi khi quá trình xử lý của chúng
không còn cần thiết. Để tìm hiểu thêm về Context, xem
Go Concurrency Patterns: Context.
Ví dụ, bạn có thể muốn:
- Kết thúc các thao tác chạy lâu, bao gồm các thao tác cơ sở dữ liệu mất quá nhiều thời gian để hoàn thành.
- Lan truyền yêu cầu hủy từ nơi khác, chẳng hạn khi client đóng kết nối.
Nhiều API dành cho lập trình viên Go bao gồm các phương thức nhận tham số
Context, giúp bạn dễ dàng sử dụng Context trong toàn bộ ứng dụng.
Hủy thao tác cơ sở dữ liệu sau khi hết thời gian chờ
Bạn có thể sử dụng Context để đặt thời gian chờ hoặc thời hạn, sau đó một
thao tác sẽ bị hủy. Để tạo một Context có thời gian chờ hoặc thời hạn, gọi
context.WithTimeout hoặc
context.WithDeadline.
Đoạn mã trong ví dụ thời gian chờ dưới đây tạo một Context và truyền vào
phương thức QueryContext
của sql.DB.
func QueryWithTimeout(ctx context.Context) {
// Create a Context with a timeout.
queryCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// Pass the timeout Context with a query.
rows, err := db.QueryContext(queryCtx, "SELECT * FROM album")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
// Handle returned rows.
}
Khi một context được tạo từ context bên ngoài, như queryCtx được tạo từ
ctx trong ví dụ này, nếu context bên ngoài bị hủy thì context dẫn xuất cũng
tự động bị hủy theo. Ví dụ, trong các HTTP server, phương thức
http.Request.Context trả về một context gắn với request đó. Context đó bị
hủy nếu HTTP client ngắt kết nối hoặc hủy HTTP request (điều này có thể xảy ra
trong HTTP/2). Truyền context của một HTTP request vào QueryWithTimeout ở
trên sẽ khiến truy vấn cơ sở dữ liệu dừng sớm nếu HTTP request tổng thể bị
hủy hoặc nếu truy vấn mất hơn năm giây.
Lưu ý: Luôn defer lời gọi đến hàm cancel được trả về khi bạn tạo một
Context mới có thời gian chờ hoặc thời hạn. Điều này giải phóng các tài
nguyên mà Context mới nắm giữ khi hàm chứa nó thoát ra. Nó cũng hủy
queryCtx, nhưng vào thời điểm hàm trả về, không còn gì đang sử dụng
queryCtx nữa.