Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 当您从一个频道读取数据并将其推送到另一个频道时,如何编写一个不会挂起的函数_Go - Fatal编程技术网

Go 当您从一个频道读取数据并将其推送到另一个频道时,如何编写一个不会挂起的函数

Go 当您从一个频道读取数据并将其推送到另一个频道时,如何编写一个不会挂起的函数,go,Go,考虑这样一个函数: func (sc *saramaConsumer) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { for msg := range claim.Messages() { sc.messages <- msg //this would hang the call if no one is reading f

考虑这样一个函数:

func (sc *saramaConsumer) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {    

    for msg  := range claim.Messages() {
         sc.messages <- msg //this would hang the call if no one is reading from sc.messages and u can never exit consume cliam
     }
}

请您的答案使用正确的格式,并添加关于您的代码的解释,以及它将如何帮助OP。谢谢。在消费者准备好之前,您希望它做什么而不是阻塞?
//we can use context to exit when some one called context cancel.
func (sc *saramaConsumer) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {    

    defer func() {
        sc.logger.Debug("message channel is closed returninig from consume Cliam", "config", sc.config)
    }()

    for {
        select {
        //if message channel is closed we exit
        case msg, ok := <-claim.Messages():
            if !ok {
                return nil
            }
            // still this would hang if we some how come here and some one called context cancel when we were here. so only solution is use go routine and launch sc.messages read there 
            // and do a time.after or use another channel to see if we can push or not.
             sc.messages <- msg 

            break
        case <-sc.config.Context().Done():
            return nil
        }
    }
}


// this is another way we can write up with out using go routine.
func (sc *saramaConsumer) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {    

    defer func() {
        sc.logger.Debug("message channel is closed returninig from consume Cliam", "config", sc.config)
    }()

    for {
        select {
        //if message channel is closed we exit
        case msg, ok := <-claim.Messages():
            if !ok {
                return nil
            }
            //we either exit on context being done or while pushing to chan.
            select {
            case sc.messages <- msg:
            case <-sc.config.Context().Done():
                return nil
            }

            break
        case <-sc.config.Context().Done():
            return nil
        }
    }
}