英文:
How to kill blocking go routine
问题
所以我正在尝试实现一个Go协程,它简单地监听Redis订阅(我使用Go-redis库进行此操作),然后在接收/处理Redis消息后,在通道上发送消息。
类似这样的代码:
func foo(redis *redis.Client, comm chan HandlerSignal) {
...
for {
msg, err := pubsub.ReceiveMessage()
sig := HandlerSignal{msg}
comm <- sig
}
}
但是我无法找到告诉Go协程在阻塞并等待Redis消息时返回的最佳方法。
有人知道这种情况下的常见做法吗?还是我完全错了?
英文:
So i'm trying to implement a go routine that simply listens on a Redis subscription (I use the Go-redis library for this) and then sends messages
on a channel after it recieves/processes the redis messages.
Something like this:
func foo(redis *redis.Client, comm chan HandlerSignal) {
...
for {
msg, err := pubsub.ReceiveMessage()
sig := HandlerSignal{msg}
comm <- sig
}
}
But I can't figure out the best way to tell the go routine to return when it is blocking and waiting for a redis message.
Does anyone know the common practice for this kind of situation or am I going about this all wrong?
答案1
得分: 2
根据我在这里看到的:https://github.com/go-redis/redis/blob/v3.2.30/pubsub.go#L253 pubsub.ReceiveMessage()
在内部使用了 ReceiveTimeout(5 * time.Second)
。为什么不使用相同的函数(就像 @Tomasz Kłak 建议的那样)?
func foo(redis *redis.Client, comm chan HandlerSignal, quit chan struct{}) {
...
for {
select {
case <-quit:
return
default:
msg, err := pubsub.ReceiveTimeout(5 * time.Second)
sig := HandlerSignal{msg}
comm <- sig
}
}
}
由于 ReceiveTimeout 会阻塞程序执行 5 秒钟,所以默认情况下不会被执行。
英文:
As I can see here: https://github.com/go-redis/redis/blob/v3.2.30/pubsub.go#L253 pubsub.ReceiveMessage()
uses internally ReceiveTimeout(5 * time.Second)
. Why not use the same function (as @Tomasz Kłak suggested)?
func foo(redis *redis.Client, comm chan HandlerSignal, quit chan struct{}) {
...
for {
select {
case <-quit:
return
default:
msg, err := pubsub.ReceiveTimeout(5 * time.Second)
sig := HandlerSignal{msg}
comm <- sig
}
}
}
Since ReceiveTimeout will block routine for the following 5 seconds, default case will be not saturated.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论