CompletionStage defensive copy

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

CompletionStage defensive copy

Pavel Rappo
Hi,

I would appreciate if you could provide some feedback on the the following
convenience (yet paranoid?) method I would like to use for defensive copying of
CompletionStage.

Thanks,
-Pavel

/**
 * Creates a defensive copy of the given {@code CompletionStage}.
 *
 * <p> Might be useful both for producers and consumers of {@code
 * CompletionStage}s.
 *
 * <p> Producers are protected from possible uncontrolled modifications
 * (cancellation, completion, obtrusion, etc.) as well as from executing
 * unknown potentially lengthy or faulty dependants in the given {@code
 * CompletionStage}'s default execution facility or synchronously.
 *
 * <p> Consumers are protected from some of the aspects of misbehaving
 * implementations (e.g. accepting results, applying functions, running
 * tasks, etc. more than once) as well as from escaping of a reference
 * to their private executor by providing a reliable proxy they use instead.
 *
 * @param src
 *         the {@code CompletionStage} to make a copy from
 * @param executor
 *         the executor used to propagate the completion
 * @param <T>
 *         the type of the {@code CompletionStage}'s result
 *
 * @return a copy of the given stage
 */
public static <T> CompletableFuture<T> copy(CompletionStage<T> src,
                                            Executor executor) {
    CompletableFuture<T> copy = new CompletableFuture<>();
    BiConsumer<T, Throwable> relay =
            (result, error) -> {
                if (error != null) {
                    copy.completeExceptionally(error);
                } else {
                    copy.complete(result);
                }
            };
    if (src.getClass() == CompletableFuture.class) {
        // No subclasses! Strictly genuine CompletableFuture.
        src.whenCompleteAsync(relay, executor);
        return copy;
    } else {
        // Don't give our executor away to an unknown CS!
        src.whenComplete(relay);
        return copy.thenApplyAsync(Function.identity(), executor);
    }
}
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: CompletionStage defensive copy

Viktor Klang
I'm not sure I understand, CompletionStage does not have any mutators?
How about changing toCompletableFuture to return a new CompletableFuture instead?

On Wed, Aug 31, 2016 at 2:55 PM, Pavel Rappo <[hidden email]> wrote:
Hi,

I would appreciate if you could provide some feedback on the the following
convenience (yet paranoid?) method I would like to use for defensive copying of
CompletionStage.

Thanks,
-Pavel

/**
 * Creates a defensive copy of the given {@code CompletionStage}.
 *
 * <p> Might be useful both for producers and consumers of {@code
 * CompletionStage}s.
 *
 * <p> Producers are protected from possible uncontrolled modifications
 * (cancellation, completion, obtrusion, etc.) as well as from executing
 * unknown potentially lengthy or faulty dependants in the given {@code
 * CompletionStage}'s default execution facility or synchronously.
 *
 * <p> Consumers are protected from some of the aspects of misbehaving
 * implementations (e.g. accepting results, applying functions, running
 * tasks, etc. more than once) as well as from escaping of a reference
 * to their private executor by providing a reliable proxy they use instead.
 *
 * @param src
 *         the {@code CompletionStage} to make a copy from
 * @param executor
 *         the executor used to propagate the completion
 * @param <T>
 *         the type of the {@code CompletionStage}'s result
 *
 * @return a copy of the given stage
 */
public static <T> CompletableFuture<T> copy(CompletionStage<T> src,
                                            Executor executor) {
    CompletableFuture<T> copy = new CompletableFuture<>();
    BiConsumer<T, Throwable> relay =
            (result, error) -> {
                if (error != null) {
                    copy.completeExceptionally(error);
                } else {
                    copy.complete(result);
                }
            };
    if (src.getClass() == CompletableFuture.class) {
        // No subclasses! Strictly genuine CompletableFuture.
        src.whenCompleteAsync(relay, executor);
        return copy;
    } else {
        // Don't give our executor away to an unknown CS!
        src.whenComplete(relay);
        return copy.thenApplyAsync(Function.identity(), executor);
    }
}
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



--
Cheers,

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest