这个需求可以通过设置上下文的超时时间来实现。具体做法如下:
- 在处理请求的函数中,创建一个带有超时时间的上下文对象,并在该上下文中执行业务逻辑。
func handlerFunc(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 执行业务逻辑,如果超时则会自动取消
err := doSomeWork(ctx)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "work done"})
}
- 如果同一个客户端再次发送请求,可以先检查上一个请求是否还在处理中。如果是,则直接返回错误信息。
var processingRequests = make(map[string]chan struct{})
func handlerFunc(c *gin.Context) {
// 检查是否有相同请求正在处理中
id := c.Request.Header.Get("X-Request-ID")
if _, ok := processingRequests[id]; ok {
c.JSON(http.StatusBadRequest, gin.H{"error": "request in progress"})
return
}
// 标记当前请求为正在处理状态
processingRequests[id] = make(chan struct{})
defer delete(processingRequests, id)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 执行业务逻辑,如果超时则会自动取消
err := doSomeWork(ctx)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "work done"})
}
在上面的代码中,我们使用一个全局变量 processingRequests 来记录正在处理中的请求。当有新请求到来时,先检查当前是否有相同请求正在处理中,如果是则直接返回错误信息;否则标记当前请求为正在处理状态,并执行业务逻辑。
需要注意的是,在并发场景下修改共享变量时需要加锁保护,这里为了简化示例代码未做加锁处理。




