首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go buffered通道通过select

Go buffered通道通过select
EN

Stack Overflow用户
提问于 2017-05-17 17:28:05
回答 3查看 333关注 0票数 1

我有两个缓冲的通道来处理入站请求:

代码语言:javascript
复制
rabbitQ = make(chan map[string]interface{}, 1000)
sqsQ = make (chan map[string]interface{}, 1000)

我的dispatcher函数如下所示:

代码语言:javascript
复制
func dispatchMessage(params map[string]interface{}) {

    if !shouldFailoverToSQS {
        select {
        case rabbitQ <- params:
            sentToRabbitMQ++
        case sqsQ <- params:
            sentToSQS++
        default:
            log.Error("Failed to dispatch mesaage to either RabbitMQ or SQS")
        }
    } else {
        sqsQ <- params
    }

}

我希望消息总是被发送到rabbitQ,除非缓冲区已经满了,但是我发现调用失败并将消息发送到sqsQ的时间大约有一半。这不是我想要的--我只想在rabbitQ已满的情况下发送到sqsQ。

我该如何强制执行此操作?

EN

回答 3

Stack Overflow用户

发布于 2017-05-17 18:30:51

根据Voker的评论,这是我想出来的:

代码语言:javascript
复制
func dispatchMessage(params map[string]interface{}) {

    //log.Debugf("Failover: %t, Len: %d", shouldFailoverToSQS, len(rabbitQ))

    if !shouldFailoverToSQS {
        select {
        case rabbitQ <- params:
            sentToRabbitMQ++
        default:
            select {
            case sqsQ <- params:
                sentToSQS++
            default:
                log.Error("Failed to dispatch mesaage to either RabbitMQ or SQS")
            }
        }
    } else {
        select {
        case sqsQ <- params:
            sentToSQS++
        default:
            log.Error("Failed to dispatch mesaage to either RabbitMQ or SQS")
        }
    }

}
票数 1
EN

Stack Overflow用户

发布于 2017-05-17 21:47:07

对于一个简洁的答案(看起来你已经从你的答案+帖子评论中得到了它),你的选择将随机选择。根据文档:

如果一个或多个通信可以继续,则通过均匀伪随机选择选择可以继续进行的单个通信。否则,如果存在默认情况,则选择该情况。如果没有默认情况,"select“语句将阻塞,直到至少有一个通信可以继续。

此外,我想我会为您提供一个根本不使用selects的答案。使用len,您可以确定有多少值在通道中排队。当然,这和你现在做的没有什么不同,但我想我会提供一些不同的东西:

代码语言:javascript
复制
const MaxChan = 1000
func dispatchMessage(params map[string]interface{}) {
    if !shouldFailoverToSQS {
        if len(rabbitQ) < MaxChan {
            sentToRabbitMQ++
        } else if len(sqsQ) < MaxChan {
            sentToSQS++
        } else {
            log.Error("Failed to dispatch mesaage to either RabbitMQ or SQS")
        }
    } else {
        if len(sqsQ) < MaxChan {
            sentToRabbitMQ++
        } else if len(rabbitQ) < MaxChan {
            sentToSQS++
        } else {
            log.Error("Failed to dispatch mesaage to either RabbitMQ or SQS")
        }
    }
}

支持文档:https://golang.org/ref/spec#Select_statements

票数 0
EN

Stack Overflow用户

发布于 2017-05-17 21:55:50

代码语言:javascript
复制
func dispatchMessage(params map[string]interface{}) {

    if !shouldFailoverToSQS {
        select {
        case rabbitQ <- params:
            sentToRabbitMQ++
        case <-time.After(time.Millisecond * 10.0): // rabbit is blocked and 10 milli sec passed.
            select {
            case sqsQ <- params:
                sentToSQS++  
            default:
            log.Error("Failed to dispatch mesaage to either RabbitMQ or SQS")
            }
        }
    } else {
        sqsQ <- params
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44020814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档