Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
oldratlee committed Feb 11, 2025
1 parent 0bf8f55 commit 5ffe352
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 41 deletions.
5 changes: 3 additions & 2 deletions cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.util.concurrent.Futures;
import edu.umd.cs.findbugs.annotations.CheckReturnValue;
import edu.umd.cs.findbugs.annotations.Nullable;
import io.foldright.cffu.CffuFactoryBuilder.CffuExecutorWrapper;
import io.foldright.cffu.tuple.Tuple2;
import io.foldright.cffu.tuple.Tuple3;
import io.foldright.cffu.tuple.Tuple4;
Expand Down Expand Up @@ -47,11 +48,11 @@ public final class CffuFactory {
// region# Builder and Constructor Methods(including internal constructors and fields)
////////////////////////////////////////////////////////////////////////////////

private final Executor defaultExecutor;
private final CffuExecutorWrapper defaultExecutor;

private final boolean forbidObtrudeMethods;

CffuFactory(Executor defaultExecutor, boolean forbidObtrudeMethods) {
CffuFactory(CffuExecutorWrapper defaultExecutor, boolean forbidObtrudeMethods) {
this.defaultExecutor = defaultExecutor;
this.forbidObtrudeMethods = forbidObtrudeMethods;
}
Expand Down
62 changes: 25 additions & 37 deletions cffu-core/src/main/java/io/foldright/cffu/CffuFactoryBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public final class CffuFactoryBuilder {
// region# Internal constructor and fields
////////////////////////////////////////////////////////////////////////////////

private final Executor defaultExecutor;
private final CffuExecutorWrapper defaultExecutor;

private volatile boolean forbidObtrudeMethods = false;

CffuFactoryBuilder(Executor defaultExecutor) {
this.defaultExecutor = makeExecutor(defaultExecutor);
this.defaultExecutor = makeCffuExecutorWrapper(defaultExecutor);
}

// endregion
Expand Down Expand Up @@ -84,48 +84,36 @@ private static CffuFactory _poisonObject() {

@Contract(pure = true)
static CffuFactory withDefaultExecutor(CffuFactory fac, Executor defaultExecutor) {
return new CffuFactory(makeExecutor(defaultExecutor), fac.forbidObtrudeMethods());
return new CffuFactory(makeCffuExecutorWrapper(defaultExecutor), fac.forbidObtrudeMethods());
}

private static Executor makeExecutor(final Executor defaultExecutor) {
private static CffuExecutorWrapper makeCffuExecutorWrapper(final Executor defaultExecutor) {
requireNonNull(defaultExecutor, "defaultExecutor is null");
// check CffuMadeExecutor interface to avoid re-wrapping.
if (defaultExecutor instanceof CffuMadeExecutor) return defaultExecutor;

// because wraps the input executor below, MUST call `screenExecutor` translation beforehand;
// otherwise the sequent operations can NOT recognize the input executor.
final Executor screenExecutor = LLCF.screenExecutor(defaultExecutor);

final Executor wrapByProviders = wrapExecutorByProviders(screenExecutor);
return wrapMadeInterface(wrapByProviders);
}

private static CffuMadeExecutor wrapMadeInterface(Executor executor) {
return new CffuMadeExecutor() {
@Override
public void execute(Runnable command) {
executor.execute(command);
}

@Override
public Executor unwrap() {
return executor;
}

@Override
public String toString() {
return "CffuMadeExecutor of executor(" + executor + ")";
}
};
if (defaultExecutor instanceof CffuExecutorWrapper) return (CffuExecutorWrapper) defaultExecutor;
else return new CffuExecutorWrapper(defaultExecutor);
}

/**
* An interface for avoiding re-wrapping.
*/
@VisibleForTesting
interface CffuMadeExecutor extends Executor {
@VisibleForTesting
Executor unwrap();
static class CffuExecutorWrapper implements Executor {
final Executor original;
final Executor unscreenedExecutor;
final Executor screenedExecutor;

CffuExecutorWrapper(Executor defaultExecutor) {
original = defaultExecutor;
unscreenedExecutor = wrapExecutorByProviders(defaultExecutor);
screenedExecutor = wrapExecutorByProviders(LLCF.screenExecutor(defaultExecutor));
}

public Executor unwrap() {
return original;
}

@Override
public void execute(Runnable command) {
original.execute(command);
}
}

private static Executor wrapExecutorByProviders(Executor executor) {
Expand Down
3 changes: 3 additions & 0 deletions cffu-core/src/main/java/io/foldright/cffu/LLCF.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.foldright.cffu;

import edu.umd.cs.findbugs.annotations.Nullable;
import io.foldright.cffu.CffuFactoryBuilder.CffuExecutorWrapper;
import org.jetbrains.annotations.Contract;

import java.util.ArrayList;
Expand Down Expand Up @@ -225,6 +226,8 @@ public static <T> boolean completeCf0(CompletableFuture<? super T> cf, @Nullable
@Contract(pure = true)
@SuppressWarnings("resource")
public static Executor screenExecutor(Executor e) {
if (e instanceof CffuExecutorWrapper) return ((CffuExecutorWrapper) e).screenedExecutor;

// Implementation note: CompletableFuture API methods already call this method internally; Only underlying
// methods that directly use an executor need to call this method (e.g. CFU#hopExecutorIfAtCfDelayerThread)
//
Expand Down
4 changes: 2 additions & 2 deletions cffu-core/src/test/java/io/foldright/cffu/CffuTestHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

package io.foldright.cffu

import io.foldright.cffu.CffuFactoryBuilder.CffuMadeExecutor
import io.foldright.cffu.CffuFactoryBuilder.CffuExecutorWrapper
import org.junit.jupiter.api.Assertions.assertSame
import org.junit.jupiter.api.Assertions.assertTrue
import java.util.concurrent.CompletableFuture
Expand All @@ -15,7 +15,7 @@ fun Cffu<*>.unwrapMadeExecutor(): Executor = defaultExecutor().unwrapMadeExecuto

fun CffuFactory.unwrapMadeExecutor(): Executor = defaultExecutor().unwrapMadeExecutor()

fun Executor.unwrapMadeExecutor(): Executor = (this as CffuMadeExecutor).unwrap()
fun Executor.unwrapMadeExecutor(): Executor = (this as CffuExecutorWrapper).unwrap()

class FooCs<T>(cf: CompletableFuture<T>) : CompletionStage<T> by cf

Expand Down

0 comments on commit 5ffe352

Please sign in to comment.