简体   繁体   English

取消 Http 处理程序请求

[英]Cancel Http handler request

I have handlers that respond to https requests.我有响应 https 请求的处理程序。 In the handlers I call a function F1() which does some application logic and connects to a mysql db and does a query.在处理程序中,我调用了一个函数 F1(),它执行一些应用程序逻辑并连接到 mysql 数据库并执行查询。 I want to know how I can use the golang context package to cancel the Db query if the client cancels the request.我想知道如果客户端取消请求,我如何使用 golang 上下文包来取消 Db 查询。 Do I need to pass the ctx to F1()?我需要将 ctx 传递给 F1() 吗? Also the code I have now will take 4 seconds even if F1() returns in less then 4. How can I return as soon as F1() returns?此外,即使 F1() 在不到 4 的时间内返回,我现在拥有的代码也将花费 4 秒。如何在 F1() 返回后立即返回?

func handler(w http.ResponseWriter, r *http.Request) {

  ctx:= r.context()

  F1()


 select {

     case <-ctx.Done():

     case <- time.After( 4*time.Second):

   }


   w.WriteHeader(http.statusOk)
  return 

 }

To begin, I highly recommend taking a look at the Context blog post to familiarize yourself with contexts, in addition to reading over the context documentation itself.首先,除了阅读context文档本身之外,我强烈建议您查看Context 博客文章以熟悉context

To address your specific questions:要解决您的具体问题:

How can you cancel the database query if the user cancels their quest?如果用户取消了他们的查询,你如何取消数据库查询?

To make this work, there are a few things you want to check:为了使这项工作正常进行,您需要检查以下几点:

  1. Ensure that your database driver (if you are using database/sql ) supports context cancellation.确保您的数据库驱动程序(如果您使用database/sql )支持上下文取消。
  2. Ensure you are using the Context variants of all available methods (eg db.QueryContext instead of db.Query ).确保您正在使用所有可用方法的 Context 变体(例如db.QueryContext而不是db.Query )。
  3. Ensure that you are passing the context (or a derivative of the context) through the stack from your HTTP request through to the database calls.确保您将上下文(或上下文的衍生物)通过堆栈从 HTTP 请求传递到数据库调用。

Do I need to pass the ctx to F1()?我需要将 ctx 传递给 F1() 吗?

Per #3 above, yes: you will need to pass the context through all intermediate calls to "connect" the database call with the request context.根据上面的#3,是的:您需要通过所有中间调用传递上下文,以将数据库调用与请求上下文“连接”。

How can I return as soon as F1() returns?如何在 F1() 返回后立即返回?

The code that you have in your question calls F1 in series, rather than concurrently, with your cancellation/timeout select .您在问题中的代码将F1与您的取消/超时select一起调用,而不是同时调用。

If you want to apply a specific deadline to your database call, use context.WithTimeout to limit how long it can take.如果您想对数据库调用应用特定的截止日期,请使用context.WithTimeout来限制它需要多长时间。 Otherwise, you do not need to do anything special: just call F1 with your context, and the rest will happen for you, no select is needed.否则,您不需要做任何特别的事情:只需使用您的上下文调用F1 ,其余的事情都会为您完成,不需要select

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM