You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by sr...@apache.org on 2018/10/30 13:37:25 UTC
[flink] branch master updated: [FLINK-8995][tests] Add keyed state
that uses custom stateful serializer to allround test job
This is an automated email from the ASF dual-hosted git repository.
srichter pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push:
new 0e9a249 [FLINK-8995][tests] Add keyed state that uses custom stateful serializer to allround test job
0e9a249 is described below
commit 0e9a249fb8953735d6af93795e95e2abec223626
Author: Stefan Richter <s....@data-artisans.com>
AuthorDate: Tue Oct 23 17:15:26 2018 +0200
[FLINK-8995][tests] Add keyed state that uses custom stateful serializer to allround test job
This closes #6909.
---
.../tests/DataStreamAllroundTestProgram.java | 8 +-
.../StatefulComplexPayloadSerializer.java | 170 +++++++++++++++++++++
2 files changed, 175 insertions(+), 3 deletions(-)
diff --git a/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/DataStreamAllroundTestProgram.java b/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/DataStreamAllroundTestProgram.java
index 513d0cf..70fdade 100644
--- a/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/DataStreamAllroundTestProgram.java
+++ b/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/DataStreamAllroundTestProgram.java
@@ -29,6 +29,7 @@ import org.apache.flink.streaming.api.functions.sink.PrintSinkFunction;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.streaming.tests.artificialstate.ComplexPayload;
+import org.apache.flink.streaming.tests.artificialstate.StatefulComplexPayloadSerializer;
import org.apache.flink.streaming.tests.avro.ComplexPayloadAvro;
import org.apache.flink.streaming.tests.avro.InnerPayLoadAvro;
import org.apache.flink.util.Collector;
@@ -91,11 +92,12 @@ public class DataStreamAllroundTestProgram {
}
return new ComplexPayload(event, KEYED_STATE_OPER_NAME);
},
- Collections.singletonList(
- new KryoSerializer<>(ComplexPayload.class, env.getConfig())), // custom KryoSerializer
+ Arrays.asList(
+ new KryoSerializer<>(ComplexPayload.class, env.getConfig()), // KryoSerializer
+ new StatefulComplexPayloadSerializer()), // custom stateful serializer
Collections.singletonList(ComplexPayload.class) // KryoSerializer via type extraction
)
- ).returns(Event.class).name(KEYED_STATE_OPER_NAME + "_Kryo");
+ ).returns(Event.class).name(KEYED_STATE_OPER_NAME + "_Kryo_and_Custom_Stateful");
// add a keyed stateful map operator, which uses Avro for state serialization
eventStream = eventStream
diff --git a/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/artificialstate/StatefulComplexPayloadSerializer.java b/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/artificialstate/StatefulComplexPayloadSerializer.java
new file mode 100644
index 0000000..89b16b6
--- /dev/null
+++ b/flink-end-to-end-tests/flink-datastream-allround-test/src/main/java/org/apache/flink/streaming/tests/artificialstate/StatefulComplexPayloadSerializer.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.streaming.tests.artificialstate;
+
+import org.apache.flink.api.common.typeutils.CompatibilityResult;
+import org.apache.flink.api.common.typeutils.ParameterlessTypeSerializerConfig;
+import org.apache.flink.api.common.typeutils.TypeSerializer;
+import org.apache.flink.api.common.typeutils.TypeSerializerConfigSnapshot;
+import org.apache.flink.api.java.typeutils.runtime.DataInputViewStream;
+import org.apache.flink.core.memory.DataInputView;
+import org.apache.flink.core.memory.DataOutputView;
+import org.apache.flink.util.InstantiationUtil;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A custom stateful serializer to test that serializers are not used concurrently.
+ */
+public class StatefulComplexPayloadSerializer extends TypeSerializer<ComplexPayload> {
+
+ private static final long serialVersionUID = 8766687317209282373L;
+
+ /** This holds the thread that currently has exclusive ownership over the serializer. */
+ private final AtomicReference<Thread> currentOwnerThread;
+
+ public StatefulComplexPayloadSerializer() {
+ this.currentOwnerThread = new AtomicReference<>(null);
+ }
+
+ @Override
+ public boolean isImmutableType() {
+ return false;
+ }
+
+ @Override
+ public TypeSerializer<ComplexPayload> duplicate() {
+ return new StatefulComplexPayloadSerializer();
+ }
+
+ @Override
+ public ComplexPayload createInstance() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ComplexPayload copy(ComplexPayload from) {
+ try {
+ Thread currentThread = Thread.currentThread();
+ if (currentOwnerThread.compareAndSet(null, currentThread)) {
+ return InstantiationUtil.deserializeObject(
+ InstantiationUtil.serializeObject(from), currentThread.getContextClassLoader());
+ } else {
+ throw new IllegalStateException("Concurrent access to type serializer detected!");
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ currentOwnerThread.set(null);
+ }
+ }
+
+ @Override
+ public ComplexPayload copy(ComplexPayload from, ComplexPayload reuse) {
+ return copy(from);
+ }
+
+ @Override
+ public int getLength() {
+ return -1;
+ }
+
+ @Override
+ public void serialize(ComplexPayload record, DataOutputView target) throws IOException {
+ try {
+ if (currentOwnerThread.compareAndSet(null, Thread.currentThread())) {
+ target.write(InstantiationUtil.serializeObject(record));
+ } else {
+ throw new IllegalStateException("Concurrent access to type serializer detected!");
+ }
+ } finally {
+ currentOwnerThread.set(null);
+ }
+ }
+
+ @Override
+ public ComplexPayload deserialize(DataInputView source) throws IOException {
+ try (final DataInputViewStream inViewWrapper = new DataInputViewStream(source)) {
+ Thread currentThread = Thread.currentThread();
+ if (currentOwnerThread.compareAndSet(null, currentThread)) {
+ return InstantiationUtil.deserializeObject(
+ inViewWrapper,
+ currentThread.getContextClassLoader());
+ } else {
+ throw new IllegalStateException("Concurrent access to type serializer detected!");
+ }
+ } catch (ClassNotFoundException e) {
+ throw new IOException("Could not deserialize object.", e);
+ } finally {
+ currentOwnerThread.set(null);
+ }
+ }
+
+ @Override
+ public ComplexPayload deserialize(ComplexPayload reuse, DataInputView source) throws IOException {
+ return deserialize(source);
+ }
+
+ @Override
+ public void copy(DataInputView source, DataOutputView target) throws IOException {
+ serialize(deserialize(source), target);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this;
+ }
+
+ @Override
+ public boolean canEqual(Object obj) {
+ return getClass().equals(obj.getClass());
+ }
+
+ @Override
+ public int hashCode() {
+ return 42;
+ }
+
+ @Override
+ public TypeSerializerConfigSnapshot<ComplexPayload> snapshotConfiguration() {
+ // type serializer singletons should always be parameter-less
+ return new ParameterlessTypeSerializerConfig<>(getSerializationFormatIdentifier());
+ }
+
+ @Override
+ public CompatibilityResult<ComplexPayload> ensureCompatibility(TypeSerializerConfigSnapshot<?> configSnapshot) {
+ if (configSnapshot instanceof ParameterlessTypeSerializerConfig
+ && isCompatibleSerializationFormatIdentifier(
+ ((ParameterlessTypeSerializerConfig<?>) configSnapshot).getSerializationFormatIdentifier())) {
+
+ return CompatibilityResult.compatible();
+ } else {
+ return CompatibilityResult.requiresMigration();
+ }
+ }
+
+ private boolean isCompatibleSerializationFormatIdentifier(String identifier) {
+ return identifier.equals(getSerializationFormatIdentifier());
+ }
+
+ private String getSerializationFormatIdentifier() {
+ return getClass().getCanonicalName();
+ }
+}