Google cloud platform apachebeam返回“;不得以任何方式改变输入值。”;使用本地直接转轮时

Google cloud platform apachebeam返回“;不得以任何方式改变输入值。”;使用本地直接转轮时,google-cloud-platform,google-cloud-dataflow,apache-beam,Google Cloud Platform,Google Cloud Dataflow,Apache Beam,我写了一个Apache Beam DoFn static class FillLocation extends DoFn<TrackingRequest, TrackingRequest> { @ProcessElement public void processElement(ProcessContext c) { TrackingRequest rq = c.element(); rq.loc

我写了一个Apache Beam DoFn

static class FillLocation extends DoFn<TrackingRequest, TrackingRequest> {
        @ProcessElement
        public void processElement(ProcessContext c) {    
            TrackingRequest rq = c.element();
            rq.location = getLocationFromIP(rq.IP);         
            c.output(rq);
        }
}

您的函数修改了input TrackingRequest元素的位置字段。这是数据流不允许的

报告说:

c.element()返回输入PCollection的当前元素。它应该被认为是不可变的。数据流运行时不会对元素进行变异,因此可以安全地进行缓存等。该元素不应被任何DoFn方法变异,因为它可能会缓存在其他位置,由数据流运行时保留,或以其他未指定的方式使用


您可以创建输入元素的副本,修改字段,然后将副本作为输出发送出去。

OK。但为什么在谷歌云上测试时它没有给出错误呢?当你改变了一个元素时,检测它有点昂贵。因此,正是测试
DirectRunner
检查了这一点,以便尽早捕获管道中的错误。如果你在谷歌云数据流上执行这样的变异,你可能会随机得到错误的结果!您可能还对以下内容感兴趣
 Input values must not be mutated in any way.
    at org.apache.beam.runners.direct.ImmutabilityEnforcementFactory$ImmutabilityCheckingEnforcement.verifyUnmodified(ImmutabilityEnforcementFactory.java:96)
    at org.apache.beam.runners.direct.ImmutabilityEnforcementFactory$ImmutabilityCheckingEnforcement.afterElement(ImmutabilityEnforcementFactory.java:71)
    at org.apache.beam.runners.direct.TransformExecutor.processElements(TransformExecutor.java:149)
    at org.apache.beam.runners.direct.TransformExecutor.run(TransformExecutor.java:107)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)