1717
1818import static net .tascalate .concurrent .SharedFunctions .cancelPromise ;
1919import static net .tascalate .concurrent .SharedFunctions .iif ;
20+ import static net .tascalate .concurrent .SharedFunctions .whenCancel ;
2021
2122import java .time .Duration ;
2223import java .util .Arrays ;
3738import java .util .function .Supplier ;
3839
3940import net .tascalate .concurrent .core .Decorator ;
40- import net .tascalate .concurrent .decorators .AbstractPromiseDecorator ;
41-
4241/**
4342 *
4443 * <p>{@link DependentPromise} implementation, i.e. concrete wrapper that may keep track origin of this promise
@@ -89,28 +88,6 @@ protected ConfigurableDependentPromise(Promise<T> delegate,
8988 this .cancellableOrigins = cancellableOrigins ;
9089 }
9190
92- private DependentPromise <T > postConstruct () {
93- if (isEmptyArray (cancellableOrigins )) {
94- // Nothing to do
95- }
96- if (isCancelled ()) {
97- // Wrapped over already cancelled Promise
98- // So result.cancel() has no effect
99- // and we have to cancel origins explicitly
100- // right after construction
101- cancelPromises (cancellableOrigins , true );
102- } else if (isDone ()) {
103- // nothing to do
104- } else {
105- delegate .whenComplete ((r , e ) -> {
106- if (isCancelled ()) {
107- cancelPromises (cancellableOrigins , true );
108- }
109- });
110- }
111- return this ;
112- }
113-
11491 public static <U > DependentPromise <U > from (Promise <U > source ) {
11592 return from (source , PromiseOrigin .NONE );
11693 }
@@ -126,7 +103,8 @@ protected <U> DependentPromise<U> wrap(Promise<U> original, CompletionStage<?>[]
126103 private static <U > DependentPromise <U > doWrap (Promise <U > original ,
127104 Set <PromiseOrigin > defaultEnlistOptions ,
128105 CompletionStage <?>[] cancellableOrigins ) {
129- if (isEmptyArray (cancellableOrigins )) {
106+ boolean noOrigins = isEmptyArray (cancellableOrigins );
107+ if (noOrigins ) {
130108 // Nothing to enlist additionally for this "original" instance
131109 if (original instanceof ConfigurableDependentPromise ) {
132110 ConfigurableDependentPromise <U > ioriginal = (ConfigurableDependentPromise <U >)original ;
@@ -138,13 +116,9 @@ private static <U> DependentPromise<U> doWrap(Promise<U> original,
138116 }
139117
140118 return new ConfigurableDependentPromise <>(
141- original , defaultEnlistOptions , cancellableOrigins
142- ).postConstruct ();
143- }
144-
145- @ Override
146- public DependentPromise <T > onCancel (Runnable code ) {
147- return new ExtraCancellationDependentPromise <>(this , code ).postConstruct ();
119+ noOrigins ? original : whenCancel (original , () -> cancelPromises (cancellableOrigins , true )),
120+ defaultEnlistOptions , cancellableOrigins
121+ );
148122 }
149123
150124 // All delay overloads delegate to these methods
@@ -750,10 +724,7 @@ public DependentPromise<T> dependent(Set<PromiseOrigin> defaultEnlistOptions) {
750724 if (identicalSets (defaultEnlistOptions , this .defaultEnlistOptions )) {
751725 return this ;
752726 } else {
753- return ConfigurableDependentPromise .from (
754- null == cancellableOrigins || cancellableOrigins .length == 0 ? delegate : cancellablePromiseOf (delegate ),
755- defaultEnlistOptions
756- );
727+ return ConfigurableDependentPromise .from (delegate , defaultEnlistOptions );
757728 }
758729 }
759730
@@ -802,31 +773,17 @@ public T join() throws CancellationException, CompletionException {
802773 public boolean isCompletedExceptionally () {
803774 return delegate .isCompletedExceptionally ();
804775 }
805-
776+
806777 @ Override
807778 public Promise <T > unwrap () {
808- if (null == cancellableOrigins || cancellableOrigins .length == 0 ) {
809- // No state collected, may optimize away own reference
810- return delegate ;
811- } else {
812- return cancellablePromiseOf (delegate );
813- }
779+ return delegate ;
814780 }
815-
781+
816782 @ Override
817783 public Promise <T > raw () {
818- if (null == cancellableOrigins || cancellableOrigins .length == 0 ) {
819- // No state collected, may optimize away own reference
820- return delegate .raw ();
821- } else {
822- return cancellablePromiseOf (delegate .raw ());
823- }
784+ return delegate .raw ();
824785 }
825786
826- protected Promise <T > cancellablePromiseOf (Promise <T > original ) {
827- return new UndecoratedCancellationPromise <>(original , cancellableOrigins );
828- }
829-
830787 @ Override
831788 public CompletableFuture <T > toCompletableFuture () {
832789 return toCompletableFuture (defaultEnlistOrigin ());
@@ -930,47 +887,4 @@ private static boolean identicalSets(Set<?> a, Set<?> b) {
930887 private static boolean isEmptyArray (Object [] array ) {
931888 return null == array || array .length == 0 ;
932889 }
933-
934- static class UndecoratedCancellationPromise <T > extends AbstractPromiseDecorator <T , Promise <T >> {
935- private final CompletionStage <?>[] dependent ;
936- UndecoratedCancellationPromise (Promise <T > original , CompletionStage <?>[] dependent ) {
937- super (original );
938- this .dependent = dependent ;
939- }
940-
941- @ Override
942- public boolean cancel (boolean mayInterruptIfRunning ) {
943- if (super .cancel (mayInterruptIfRunning )) {
944- cancelPromises (dependent , mayInterruptIfRunning );
945- return true ;
946- } else {
947- return false ;
948- }
949- }
950-
951- @ Override
952- public Promise <T > unwrap () {
953- return unwrap (Promise ::unwrap );
954- }
955-
956- @ Override
957- public Promise <T > raw () {
958- return unwrap (Promise ::raw );
959- }
960-
961- private Promise <T > unwrap (Function <Promise <T >, Promise <T >> fn ) {
962- Promise <T > unwrapped = fn .apply (delegate );
963- if (unwrapped == delegate ) {
964- return this ;
965- } else {
966- return new UndecoratedCancellationPromise <>(unwrapped , dependent );
967- }
968- }
969-
970- @ Override
971- protected <U > Promise <U > wrap (CompletionStage <U > original ) {
972- // No wrapping by definition
973- return (Promise <U >)original ;
974- }
975- }
976890}
0 commit comments