取消正在进行的操作
2 分钟阅读
Canceling in-progress operations - 取消正在进行的操作
您可以通过使用Go context.Context来管理正在进行的操作。Context
是一个标准的Go数据值,可以报告它所表示的整体操作是否已经被取消,是否不再需要。通过在应用程序中的函数调用和服务中传递context.Context
,这些(函数调用和服务)可以提前停止工作,并在不再需要其处理时返回一个错误。关于Context
的更多信息,请参阅 Go并发模式:Context。
例如,您可能想:
- 结束长期运行的操作,包括需要太长时间才能完成的数据库操作。
- 传播来自其他地方的取消请求,例如当客户端关闭连接时。
许多为Go开发者提供的API都包含接受Context
实参的方法,这使得在整个应用程序中更容易使用Context
。
在超时后取消数据库操作
您可以使用 Context
来设置一个超时或最后期限,超时后的操作将被取消。要派生一个带有超时或最后期限的Context
,请调用context.WithTimeout或context.WithDeadline。
下面的超时例子中的代码派生了一个Context,并将其传递给sql.DB
QueryContext方法。
|
|
当一个上下文派生自一个外部上下文时,就像本例中queryCtx
派生自ctx
一样,如果外部上下文被取消,那么派生的上下文也会被自动取消。例如,在HTTP服务器中,http.Request.Context
方法返回一个与请求相关的上下文。如果HTTP客户端断开连接或取消HTTP请求(在HTTP/2中可能),则该上下文就会被取消。将HTTP请求的上下文传递给上面的QueryWithTimeout
会导致数据库查询提前停止,如果整个HTTP请求被取消或者查询时间超过5秒的话。
注意
当您创建一个有超时或截止日期的新
Context
时,(一定记得)始终推迟对cancel
函数的调用。这将在外层函数退出时释放新Context
所持有的资源。它也会取消queryCtx
,但是当函数返回时,就不会再有任何东西使用queryCtx
了。