
com.hazelcast.spi.impl.DeserializingCompletableFuture Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
*
* Licensed 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 com.hazelcast.spi.impl;
import com.hazelcast.internal.serialization.InternalSerializationService;
import com.hazelcast.internal.serialization.SerializationService;
import com.hazelcast.internal.serialization.Data;
import com.hazelcast.internal.util.ConcurrencyUtil;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Decorates {@link InternalCompletableFuture} to supply:
*
* - optional value deserialization
* - custom default async executor
*
*/
@SuppressWarnings("checkstyle:methodcount")
public class DeserializingCompletableFuture extends InternalCompletableFuture {
/**
* Reference to serialization service; can be {@code null} when {@code deserialize} is {@code false}
*/
private final InternalSerializationService serializationService;
/**
* Default executor for execution of callbacks registered with async methods without
* explicit {@link Executor} argument (eg. {@link #whenCompleteAsync(BiConsumer)}.
*/
private final Executor defaultAsyncExecutor;
/**
* When {@code true}, a completion value of type {@link Data} will be deserialized
* before returned from one of the blocking results getter methods ({@link #get()}, {@link #join()} etc.)
* or before passed as argument to callbacks such as {@link #thenAccept(Consumer)}.
*/
private final boolean deserialize;
public DeserializingCompletableFuture() {
this(null, ConcurrencyUtil.getDefaultAsyncExecutor(), false);
}
public DeserializingCompletableFuture(Executor defaultAsyncExecutor) {
this(null, defaultAsyncExecutor, false);
}
public DeserializingCompletableFuture(SerializationService serializationService, boolean deserialize) {
this(serializationService, ConcurrencyUtil.getDefaultAsyncExecutor(), deserialize);
}
public DeserializingCompletableFuture(SerializationService serializationService, Executor defaultAsyncExecutor,
boolean deserialize) {
this.serializationService = (InternalSerializationService) serializationService;
this.defaultAsyncExecutor = defaultAsyncExecutor;
this.deserialize = deserialize;
}
@Override
public V get() throws InterruptedException, ExecutionException {
return resolve(super.get());
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return resolve(super.get(timeout, unit));
}
@Override
public V getNow(V valueIfAbsent) {
V value = super.getNow(valueIfAbsent);
return (deserialize && value instanceof Data) ? serializationService.toObject(value)
: value;
}
@Override
public V join() {
return resolve(super.join());
}
@Override
public V joinInternal() {
return resolve(super.joinInternal());
}
@Override
public CompletableFuture thenApply(Function super V, ? extends U> fn) {
return super.thenApply(new DeserializingFunction<>(fn));
}
@Override
public CompletableFuture thenApplyAsync(Function super V, ? extends U> fn) {
return super.thenApplyAsync(new DeserializingFunction<>(fn), defaultAsyncExecutor);
}
@Override
public CompletableFuture thenApplyAsync(Function super V, ? extends U> fn, Executor executor) {
return super.thenApplyAsync(new DeserializingFunction<>(fn), executor);
}
@Override
public CompletableFuture thenAccept(Consumer super V> action) {
return super.thenAccept(new DeserializingConsumer<>(action));
}
@Override
public CompletableFuture thenAcceptAsync(Consumer super V> action) {
return super.thenAcceptAsync(new DeserializingConsumer<>(action), defaultAsyncExecutor);
}
@Override
public CompletableFuture thenAcceptAsync(Consumer super V> action, Executor executor) {
return super.thenAcceptAsync(new DeserializingConsumer<>(action), executor);
}
@Override
public CompletableFuture thenRun(Runnable action) {
return super.thenRun(action);
}
@Override
public CompletableFuture thenRunAsync(Runnable action) {
return super.thenRunAsync(action, defaultAsyncExecutor);
}
@Override
public CompletableFuture thenRunAsync(Runnable action, Executor executor) {
return super.thenRunAsync(action, executor);
}
@Override
public CompletableFuture thenCombine(CompletionStage extends U> other,
BiFunction super V, ? super U, ? extends V1> fn) {
return super.thenCombine(other, new DeserializingBiFunction<>(fn));
}
@Override
public CompletableFuture thenCombineAsync(CompletionStage extends U> other,
BiFunction super V, ? super U, ? extends V1> fn) {
return super.thenCombineAsync(other, new DeserializingBiFunction<>(fn), defaultAsyncExecutor);
}
@Override
public CompletableFuture thenCombineAsync(CompletionStage extends U> other,
BiFunction super V, ? super U, ? extends V1> fn, Executor executor) {
return super.thenCombineAsync(other, new DeserializingBiFunction<>(fn), executor);
}
@Override
public CompletableFuture thenAcceptBoth(CompletionStage extends U> other,
BiConsumer super V, ? super U> action) {
return super.thenAcceptBoth(other, new DeserializingBiConsumer<>(action));
}
@Override
public CompletableFuture thenAcceptBothAsync(CompletionStage extends U> other,
BiConsumer super V, ? super U> action) {
return super.thenAcceptBothAsync(other, new DeserializingBiConsumer<>(action), defaultAsyncExecutor);
}
@Override
public CompletableFuture thenAcceptBothAsync(CompletionStage extends U> other,
BiConsumer super V, ? super U> action, Executor executor) {
return super.thenAcceptBothAsync(other, new DeserializingBiConsumer<>(action), executor);
}
@Override
public CompletableFuture runAfterBoth(CompletionStage> other, Runnable action) {
return super.runAfterBoth(other, action);
}
@Override
public CompletableFuture runAfterBothAsync(CompletionStage> other, Runnable action) {
return super.runAfterBothAsync(other, action, defaultAsyncExecutor);
}
@Override
public CompletableFuture runAfterBothAsync(CompletionStage> other, Runnable action, Executor executor) {
return super.runAfterBothAsync(other, action, executor);
}
@Override
public CompletableFuture applyToEither(CompletionStage extends V> other, Function super V, U> fn) {
return super.applyToEither(other, new DeserializingFunction<>(fn));
}
@Override
public CompletableFuture applyToEitherAsync(CompletionStage extends V> other, Function super V, U> fn) {
return super.applyToEitherAsync(other, new DeserializingFunction<>(fn), defaultAsyncExecutor);
}
@Override
public CompletableFuture applyToEitherAsync(CompletionStage extends V> other, Function super V, U> fn,
Executor executor) {
return super.applyToEitherAsync(other, new DeserializingFunction<>(fn), executor);
}
@Override
public CompletableFuture acceptEither(CompletionStage extends V> other, Consumer super V> action) {
return super.acceptEither(other, new DeserializingConsumer<>(action));
}
@Override
public CompletableFuture acceptEitherAsync(CompletionStage extends V> other, Consumer super V> action) {
return super.acceptEitherAsync(other, new DeserializingConsumer<>(action), defaultAsyncExecutor);
}
@Override
public CompletableFuture acceptEitherAsync(CompletionStage extends V> other, Consumer super V> action,
Executor executor) {
return super.acceptEitherAsync(other, new DeserializingConsumer<>(action), executor);
}
@Override
public CompletableFuture runAfterEither(CompletionStage> other, Runnable action) {
return super.runAfterEither(other, action);
}
@Override
public CompletableFuture runAfterEitherAsync(CompletionStage> other, Runnable action) {
return super.runAfterEitherAsync(other, action, defaultAsyncExecutor);
}
@Override
public CompletableFuture runAfterEitherAsync(CompletionStage> other, Runnable action, Executor executor) {
return super.runAfterEitherAsync(other, action, executor);
}
@Override
public CompletableFuture thenCompose(Function super V, ? extends CompletionStage> fn) {
return super.thenCompose(new DeserializingFunction<>(fn));
}
@Override
public CompletableFuture thenComposeAsync(Function super V, ? extends CompletionStage> fn) {
return super.thenComposeAsync(new DeserializingFunction<>(fn), defaultAsyncExecutor);
}
@Override
public CompletableFuture thenComposeAsync(Function super V, ? extends CompletionStage> fn, Executor executor) {
return super.thenComposeAsync(new DeserializingFunction<>(fn), executor);
}
@Override
public CompletableFuture whenComplete(BiConsumer super V, ? super Throwable> action) {
if (!deserialize) {
return super.whenComplete(new DeserializingBiConsumer<>(action));
} else {
return new DelegatingCompletableFuture<>(serializationService,
super.whenComplete(new DeserializingBiConsumer<>(action)));
}
}
@Override
public CompletableFuture whenCompleteAsync(BiConsumer super V, ? super Throwable> action) {
if (!deserialize) {
return super.whenCompleteAsync(new DeserializingBiConsumer<>(action), defaultAsyncExecutor);
} else {
return new DelegatingCompletableFuture<>(serializationService,
super.whenCompleteAsync(new DeserializingBiConsumer<>(action)
, defaultAsyncExecutor));
}
}
@Override
public CompletableFuture whenCompleteAsync(BiConsumer super V, ? super Throwable> action, Executor executor) {
if (!deserialize) {
return super.whenCompleteAsync(new DeserializingBiConsumer<>(action), executor);
} else {
return new DelegatingCompletableFuture<>(serializationService,
super.whenCompleteAsync(new DeserializingBiConsumer<>(action), executor));
}
}
@Override
public CompletableFuture handle(BiFunction super V, Throwable, ? extends U> fn) {
return super.handle(new DeserializingBiFunction<>(fn));
}
@Override
public CompletableFuture handleAsync(BiFunction super V, Throwable, ? extends U> fn) {
return super.handleAsync(new DeserializingBiFunction<>(fn), defaultAsyncExecutor);
}
@Override
public CompletableFuture handleAsync(BiFunction super V, Throwable, ? extends U> fn, Executor executor) {
return super.handleAsync(new DeserializingBiFunction<>(fn), executor);
}
@Override
public CompletableFuture exceptionally(Function fn) {
if (!deserialize) {
return super.exceptionally(fn);
} else {
return new DelegatingCompletableFuture<>(serializationService, super.exceptionally(fn));
}
}
private V resolve(Object object) {
if (deserialize && object instanceof Data data) {
// we need to deserialize.
object = serializationService.toObject(data);
//todo do we need to call dispose data here
serializationService.disposeData(data);
}
return (V) object;
}
class DeserializingFunction implements Function {
private final Function delegate;
DeserializingFunction(Function delegate) {
if (delegate == null) {
throw new NullPointerException();
}
this.delegate = delegate;
}
@Override
public R apply(E e) {
return delegate.apply(deserialize ? serializationService.toObject(e) : e);
}
}
class DeserializingConsumer implements Consumer {
private final Consumer delegate;
DeserializingConsumer(Consumer delegate) {
if (delegate == null) {
throw new NullPointerException();
}
this.delegate = delegate;
}
@Override
public void accept(E e) {
delegate.accept(deserialize ? serializationService.toObject(e) : e);
}
}
class DeserializingBiFunction implements BiFunction {
private final BiFunction delegate;
DeserializingBiFunction(BiFunction delegate) {
if (delegate == null) {
throw new NullPointerException();
}
this.delegate = delegate;
}
@Override
public R apply(T t, U u) {
return delegate.apply(deserialize ? serializationService.toObject(t) : t,
deserialize ? serializationService.toObject(u) : u);
}
}
class DeserializingBiConsumer implements BiConsumer {
private final BiConsumer delegate;
DeserializingBiConsumer(BiConsumer delegate) {
if (delegate == null) {
throw new NullPointerException();
}
this.delegate = delegate;
}
@Override
public void accept(T t, U u) {
delegate.accept(deserialize ? serializationService.toObject(t) : t,
deserialize ? serializationService.toObject(u) : u);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy