douxi7219 2019-02-21 09:17
浏览 22

根据Go lang中的类型处理案件的更好方法

I'm new to Go lang and I could use some suggestions on how to refactor the code. All I got to do is depending on the success or error from Sarama (Apache Kafka thing in go) I need to log and forward it further. So far my code looks like this

go func() {
    for err := range producer.Errors() {
        batchID := err.Msg.Metadata.(ackMeta).batchID # notice the struct here
        statusChan := err.Msg.Metadata.(ackMeta).statusChan
        statusChan <- false
        close(statusChan)
        logs.Debug(appName, "Signalled failure on statusChan for batch ", batchID)
        logs.Error(appName, "Failed to publish data to analyzer for batchID: ", batchID, err)
    }
}()

go func() {
    for succ := range producer.Successes() {
        batchID := succ.Metadata.(ackMeta).batchID        # notice the struct here
        statusChan := succ.Metadata.(ackMeta).statusChan
        statusChan <- true
        close(statusChan)
        logs.Debug(appName, "Signalled success on statusChan for batch ", batchID)
        logs.Debug(appName, "Successfully  published data to analyzer:", succ.Topic, succ.Key, succ.Partition, succ.Offset, succ.Metadata)
    }

I think I can do a better job and wrap the whole thing in a single function but so far I can't think of any other apart from using the switch case as shown here

func checkSuccessOrFailAck(msg interface{}) {
    switch msgType := msg.(type) {
    case producer.Errors:
        batchID := msg.Msg.Metadata.(ackMeta).batchID
        statusChan := msg.Msg.Metadata.(ackMeta).statusChan
        statusChan <- false
        close(statusChan)
        logs.Debug(appName, "Signalled failure on statusChan for batch ", batchID)
        logs.Error(appName, "Failed to publish data to analyzer for batchID: ", batchID, msg)
    case producer.Successes:
        batchID := msg.Metadata.(ackMeta).batchID
        statusChan := msg.Metadata.(ackMeta).statusChan
        statusChan <- true
        close(statusChan)
        logs.Debug(appName, "Signalled success on statusChan for batch ", batchID)
        logs.Debug(appName, "Successfully  published data to analyzer:", succ.Topic, succ.Key, succ.Partition, succ.Offset, succ.Metadata)
    }

}

The types of messages are different and so is the way I extract the attributes from it. But I'm not happy with this approach as the statements are more than the previous one. Could there be a better way to think to write ?

  • 写回答

2条回答 默认 最新

  • dongyuan6949 2019-02-21 13:32
    关注

    First, it's not clear if the second code works at all. Since Errors() and Successes() return channels, you'd need to select to read from both of them simultaneously without blocking either.

    Since succ and err have different types in the code, I'm not sure you can do it much shorter than your original sample. Go doesn't have generics yet, so writing code that would unify the two is challenging. If you really need it I'd try to find the closest points where the type is the same - it should be easier to unify code from that point on. for example err.Msg and succ are the same type?

    Moreover, even if Go had generics already, it's not clear unifying these would be a win. Go's philosophy is that a little code repetition is better than over-complicated abstractions. The code isn't the shortest it could be in theory, but it's explicit and clear.

    评论

报告相同问题?

悬赏问题

  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行