2016-02-19 21 views
1

因此,我試圖實現一個簡單地偵聽Redis訂閱(我使用Go-Redis庫)的去例程,然後在它接收/處理後在通道上發送消息 redis消息。如何殺死阻止去例行程序

事情是這樣的:

func foo(redis *redis.Client, comm chan HandlerSignal) { 

    ... 

    for { 
     msg, err := pubsub.ReceiveMessage() 
     sig := HandlerSignal{msg} 
     comm <- sig 
    } 
} 

但我想不出告訴去例程返回時被阻塞和等待Redis的消息的最佳方式。

有沒有人知道這種情況的常見做法,還是我對這一切都有錯?

+1

是的,添加另一個退出/中止通道,然後在for循環中放入一個選擇,並在該通道返回時收聽,如果它發出信號。 – evanmcdonnal

+1

使用[ReceiveTimeout](https://godoc.org/gopkg.in/redis.v3#PubSub.ReceiveTimeout) – tumdum

+1

與其他Redis客戶端一樣,您可以通過從所有渠道取消訂閱客戶端來告訴訂閱者停止閱讀。這不受go-redis支持。另一種方法是在收到區分的哨兵消息時打破循環,並從應用程序發送該消息。 –

回答

2

正如我在這裏看到的:https://github.com/go-redis/redis/blob/v3.2.30/pubsub.go#L253pubsub.ReceiveMessage()內部使用ReceiveTimeout(5 * time.Second)。爲什麼不使用相同的功能(如@TomaszKł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秒內阻止例程,因此默認情況下將不會飽和。