【问题标题】:gob: type mismatch: no fields matched compiling decoder - Golanggob:类型不匹配:没有匹配的字段编译解码器 - Golang
【发布时间】:2019-09-12 00:19:09
【问题描述】:

我在两个不同的流上使用 PubSub,我们从一个流接收消息,运行一些逻辑,如果它符合某些条件,我们将其发布到第二个流。第二个流也在一个 goroutine 中被接收。

现在,我有两个主要功能HandleMessageHandleRetry,前者来自第一个流,第二个来自第二个流。

HandleMessage的相关代码如下:

    if c.handler.ShouldProcess(tx) {
        err := c.handler.Process(tx)
        if err != nil {
            c.log.
                WithError(err).
                WithField("tx_hash", tx.TxHash.String()).
                Error("failed to process")

            retryMsg := RetryMessage{
                Transaction:                 tx,
                RemainingProcessingAttempts: c.config.MaxProcessingAttempts,
                LastAttempt:                 time.Now(),
            }

            data, err := pubsub.EncodeMessage(retryMsg)
            if err != nil {
                c.log.WithError(err).Error("failed to convert retry msg to byte slice")
            }

            id, err := c.retryQueue.Publish(context.Background(), &pubsub.Message{Data: data})
            if err != nil {
                c.log.WithError(err).
                    WithField("id", id).
                    Error("failed to publish message to retry queue")
            }
        }
    }

HandleRetry 中,函数以

打开
    retryTx := new(RetryMessage)
    err := pubsub.DecodeMessage(msg.Data, retryTx)
    if err != nil {
        c.log.WithError(err).
            Error("failed to decode message: not a retry tx")
        msg.Ack()
        return
    }

对于由HandleRetry 处理的RetryQueue -- 除了从HandleMessage 发布的消息外,没有其他输入

但是,我不断收到 gob 解码错误提示

level=error msg="failed to decode message: not a retry tx" env=LOCAL error="gob: type mismatch: no fields matched compiling decoder for RetryMessage"

RetryMessage 看起来像这样

type RetryMessage struct {
    Transaction                 *firehose.Transaction
    RemainingProcessingAttempts int
    LastAttempt                 time.Time
}

编解码函数如下

// EncodeMessage convert an arbitrary interface into a byte slice.
func EncodeMessage(data interface{}) ([]byte, error) {
    var buf bytes.Buffer

    enc := gob.NewEncoder(&buf)

    err := enc.Encode(data)
    if err != nil {
        return nil, err
    }

    return buf.Bytes(), nil
}

// DecodeMessage decodes message data into the provided interface.
func DecodeMessage(data []byte, dest interface{}) error {
    buf := bytes.NewBuffer(data)
    dec := gob.NewDecoder(buf)
    return dec.Decode(dest)
}

【问题讨论】:

  • 你可以尝试在dec.Decode(dest)之前打印dest的类型。确保它是 RetryMessage 类型的

标签: go google-cloud-pubsub


【解决方案1】:

HandleMessage的这段代码中:

        data, err := pubsub.EncodeMessage(retryMsg)
        if err != nil {
            c.log.WithError(err).Error("failed to convert retry msg to byte slice")
        }

错误被忽略,发布消息的data 字段填充了一个可能错误的值。检查您是否在日志中看到“未能将重试消息转换为字节片”。

【讨论】:

  • 我修复了错误,尽管它无关。 gob 解码器不喜欢 RetryMessage 内部的 Transaction 是一个指针,我将其更改为结构的副本并且它可以工作
  • 您最好添加这个答案然后接受它。
猜你喜欢
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多