This is an automated email from the ASF dual-hosted git repository. dkuppitz pushed a commit to branch TINKERPOP-2126 in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit b19d9cfca7a8e2ce400dc120ce71b5be60aab0dc Author: Daniel Kuppitz <[email protected]> AuthorDate: Tue Jan 22 15:07:09 2019 -0700 TINKERPOP-2126 Fixed concurrency issue in `ObjectWritable::toString()`. --- CHANGELOG.asciidoc | 2 +- .../gremlin/hadoop/structure/io/ObjectWritable.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index e0e4620..48bd270 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -30,7 +30,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima * Added `globalFunctionCacheEnabled` to the `GroovyCompilerGremlinPlugin` to allow that cache to be disabled. * Added `globalFunctionCacheEnabled` override to `SessionOpProcessor` configuration. * Added status code to `GremlinServerError` so that it would be more directly accessible during failures. -* Fixed a concurrency issue in `TraverserSet`. +* Fixed concurrency issues in `TraverserSet::toString()` and `ObjectWritable::toString()`. * Fixed a bug in `InlineFilterStrategy` that mixed up and's and or's when folding merging conditions together. [[release-3-3-5]] diff --git a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/io/ObjectWritable.java b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/io/ObjectWritable.java index 0379ee6..13cea4e 100644 --- a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/io/ObjectWritable.java +++ b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/io/ObjectWritable.java @@ -30,13 +30,14 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.util.ConcurrentModificationException; +import java.util.Objects; /** * @author Marko A. Rodriguez (http://markorodriguez.com) */ public final class ObjectWritable<T> implements WritableComparable<ObjectWritable>, Serializable { - private static final String NULL = "null"; private static final ObjectWritable<MapReduce.NullObject> NULL_OBJECT_WRITABLE = new ObjectWritable<>(MapReduce.NullObject.instance()); T t; @@ -45,7 +46,7 @@ public final class ObjectWritable<T> implements WritableComparable<ObjectWritabl } public ObjectWritable(final T t) { - this.t = t; + this.set(t); } public T get() { @@ -58,7 +59,15 @@ public final class ObjectWritable<T> implements WritableComparable<ObjectWritabl @Override public String toString() { - return null == this.t ? NULL : this.t.toString(); + // Spark's background logging apparently tries to log a `toString()` of certain objects while they're being + // modified, which then throws a ConcurrentModificationException. We probably can't make any arbitrary object + // thread-safe, but we can easily retry on such cases and eventually we should always get a result. + while (true) { + try { + return Objects.toString(this.t); + } + catch (ConcurrentModificationException ignored) { } + } } @Override
