为什么编码器在Cobine阶段尝试解码标签列表?

时间:2016-11-14 11:12:24

标签: google-cloud-dataflow

我正在尝试在未绑定的流中合并一些记录。我确实有一个PCollection<KV<String, TableRow>>我正在尝试使用我自己的累加器类EventAccumulator进行组合,其中包含两个类型为LongTableRow的字段,这些字段在上述流中从每个窗口中选取

我已经创建了自己的clas EventAccumulatorCoder,我正在管道中注册这个来处理EventAccumulator的实例。编码器看起来如下:

public class EventAccumulatorCoder extends AtomicCoder<EventAccumulator> {
    public static EventAccumulatorCoder of() {
        return new EventAccumulatorCoder();
    }

    @Override
    public void encode(EventAccumulator value, OutputStream outputStream, Context context) throws IOException {
        TableRowJsonCoder.of().encode(value.getEarliestEvent(), outputStream, context);
        BigEndianLongCoder.of().encode(value.getEarliestTimestamp(), outputStream, context);
    }

    @Override
    public EventAccumulator decode(InputStream inputStream, Context context) throws IOException {
        TableRow row = TableRowJsonCoder.of().decode(inputStream, context);
        Long timestamp = BigEndianLongCoder.of().decode(inputStream, context);
        return new EventAccumulator(timestamp, row);
    }
}

在管道执行期间,我收到以下错误:

java.lang.IllegalStateException: Unable to decode tag list using EventAccumulatorCoder
    at com.google.cloud.dataflow.sdk.runners.worker.WindmillStateReader.tagListPageValues(WindmillStateReader.java:576)
    at com.google.cloud.dataflow.sdk.runners.worker.WindmillStateReader.consumeTagList(WindmillStateReader.java:599)
...
Caused by: com.google.cloud.dataflow.sdk.coders.CoderException: java.io.EOFException
    at com.google.cloud.dataflow.sdk.coders.BigEndianLongCoder.decode(BigEndianLongCoder.java:62)
...
Caused by: java.io.EOFException
    at java.io.DataInputStream.readFully(DataInputStream.java:197)
    at java.io.DataInputStream.readLong(DataInputStream.java:416)

你们有没有想过为什么编码器试图解码标签列表?我需要补充一点,组合阶段的输入是前一个管道步骤的侧输出。

1 个答案:

答案 0 :(得分:1)

您需要使用context.nested() - 您的编码器非常像KvCoder,请参阅KvCoder如何使用here

您正在获取EOFException,因为TableRowJsonCoder.of().encode(value.getEarliestEvent(), outputStream, context)在使用非嵌套上下文时会消耗整个流,这就是下一行BigEndianLongCoder.decode的原因,击中EOF。