【发布时间】:2019-04-13 21:52:06
【问题描述】:
我正在编写一个对传入请求进行排队的应用程序。如果一个请求已经在队列中超过了一定的时间,我想抛出一个超时。我正在做这与时间。之后:
timeoutCh := time.After(5 * time.Second)
select {
case <-timeoutCh:
//throw timeout 504
case <-processing:
//process request
}
处理通道(连同请求)被放入队列中,当一个请求被取出处理时,我向通道发送一个信号来命中case语句:
processing <- true
这样做的问题是如果已经选择了 timeoutCh,处理通道会阻塞,所以我需要一些方法来检查请求是否超时。
我考虑过使用共享原子布尔值,但如果我这样做:
case <-timeoutCh:
requestTimedOut = true
然后在发送到处理通道之前检查布尔值,仍然存在竞争条件,因为可能已经选择了 timeoutCh 情况,但布尔值尚未设置为 true!
有没有一种惯用的方式来处理 Go 中的这种同步问题?
【问题讨论】:
-
这是您要解决的更高级别的问题吗:从队列中删除请求时,如果请求在队列中的时间超过某个指定的持续时间,则丢弃该请求并报错。跨度>
-
是的——这就是我要解决的问题!
-
使用
struct { r Request, enqueueTime time.Time }作为队列元素类型并在从队列中删除元素时检查入队时间是否有效?if time.Since(e.enqueueTime) > duration { /* discard with error */ } -
这几乎可以工作,只是一旦超过超时就不会返回 504。
-
如何处理双向通道并从选择中的超时块发送信号?这样,您的队列可以通过检查
<-processing来丢弃请求。或者有一个专门用于该用途的单独频道,例如hasTimedOut。 (编辑:我想我误解了你的问题忽略我)
标签: go synchronization timeout