src/main/java/org/michailov/async/WhenReady.java
private static<S, R> void applyLoopAsync(CompletableFuture<R> future, WhenReadyArguments<S, R> args, Throwable exception) {
        try {
            if (exception != null) {
                completeFutureExceptionallySafe(future, exception);
            }
            
            if (!mustExit(future, args)) {
                R result = null;
       
                if (args.mode == WhenReadyMode.ONCE) {
                    if (args.ready.test(args.state)) {
                        result = args.action.apply(args.state);
                    }
                }
                else {
                    // Call action() as long as possible to avoid excessive rescheduling. 
                    while (args.ready.test(args.state) && !args.done.test(args.state)) {
                        result = args.action.apply(args.state);
                    }
                }
                
                if (args.done.test(args.state)) {
                    String logMessage = String.format("future=%1$d , class=unknown , event=Done", future.hashCode());
                    Logger.getLogger().finer(logMessage);
                    
                    completeFutureSafe(future, result);
                }
                
                if (!mustExit(future, args)) {
                    Executor.execute(() -> startApplyLoopAsync(future, args));
                }
            }
        }
        catch (Throwable ex) {
            completeFutureExceptionallySafe(future, ex);
        }
    }
/**
     * Continuation of {@link #completeAsync} for all {@link #applyAsync} and {@link #startApplyLoop} overloads.
     */
Continuation of  #completeAsync for all  #applyAsync and  #startApplyLoop overloads.
Continuation of #completeAsync for all #applyAsync and #startApplyLoop overloads .
private static<S, R> void applyLoopAsync(CompletableFuture<R> future, WhenReadyArguments<S, R> args, Throwable exception) {
        try {
            if (exception != null) {
                completeFutureExceptionallySafe(future, exception);
            }
            if (!mustExit(future, args)) {
                R result = null;
                if (args.mode == WhenReadyMode.ONCE) {
                    if (args.ready.test(args.state)) {
                        result = args.action.apply(args.state);
                    }
                }
                else {
                    while (args.ready.test(args.state) && !args.done.test(args.state)) {
                        result = args.action.apply(args.state);
                    }
                }
                if (args.done.test(args.state)) {
                    String logMessage = String.format("future=%1$d , class=unknown , event=Done", future.hashCode());
                    Logger.getLogger().finer(logMessage);
                    completeFutureSafe(future, result);
                }
                if (!mustExit(future, args)) {
                    Executor.execute(() -> startApplyLoopAsync(future, args));
                }
            }
        }
        catch (Throwable ex) {
            completeFutureExceptionallySafe(future, ex);
        }
    }
private static < S , R > void applyLoopAsync ( CompletableFuture < R > future , WhenReadyArguments < S , R > args , Throwable exception ) { try { if ( exception != null ) { completeFutureExceptionallySafe ( future , exception ) ; } if ( ! mustExit ( future , args ) ) { R result = null ; if ( args . mode == WhenReadyMode . ONCE ) { if ( args . ready . test ( args . state ) ) { result = args . action . apply ( args . state ) ; } } else { while ( args . ready . test ( args . state ) && ! args . done . test ( args . state ) ) { result = args . action . apply ( args . state ) ; } } if ( args . done . test ( args . state ) ) { String logMessage = String . format ( "future=%1$d , class=unknown , event=Done" , future . hashCode ( ) ) ; Logger . getLogger ( ) . finer ( logMessage ) ; completeFutureSafe ( future , result ) ; } if ( ! mustExit ( future , args ) ) { Executor . execute ( ( ) -> startApplyLoopAsync ( future , args ) ) ; } } } catch ( Throwable ex ) { completeFutureExceptionallySafe ( future , ex ) ; } }
Continuation of {@link #completeAsync} for all {@link #applyAsync} and {@link #startApplyLoop} overloads.
Continuation of { @link #completeAsync } for all { @link #applyAsync } and { @link #startApplyLoop } overloads .
// Call action() as long as possible to avoid excessive rescheduling. 
