Hi Peter, et.al.,

I have no particular issue with adding waitForUninterruptibly but it does not
help with the lack of scalability when handling many processes.
It requires a thread to do the waiting whether from a specific caller or a thread pool

The intent of proving a Future/CF was to allow the implementation the choice of how to wait for termination including those mechanisms that do not require dedicating
a thread to the  monitoring of termination and taking an action thereafter.
On Windows for example, WaitForMultipleObjects can be used to multiplex the waiting.

With Lambda providing the behavior to CF, the lambda can capture the reference
to the Process[Handle] without relying on the generic type of the CF.

Process p = ...;
CompletableFuture<ProcessHandle> cf = p.completableFuture();
cf.thenRunAsync(  () -> {int exitValue = p.getExitValue(); ....   })

Or using CompletableFuture<Void> would force the developer to capture the Process[Handle]
reference as needed.

Another alternative is a simple method onTermination(Consumer<ProcessHandle> consumer) that makes it easy to use lambdas to provide the behavior. The implementation
can use the same Thread pool as CF to provide the thread. It has the same
threading issues as CF but with less complexity in the interface.

An alternative without an argument would be onTerminate(Runnable runnable) and it would generally be the case that the lambda would need to have a binding for the
reference to the Process/ProcessHandle.

Roger

On 2/13/2015 10:34 AM, Peter Levart wrote:
On 02/13/2015 04:18 PM, David M. Lloyd wrote:
On 02/13/2015 09:15 AM, Peter Levart wrote:
On 02/13/2015 03:22 PM, Paul Sandoz wrote:
>It*is* inconvenient for the user to have to use wildcards in specifying types:
>
>CompletableFuture<? extends Process> cf = process.completableFuture();
>
>...but it doesn't hinder the use of above 'cf' quite so much as 'len' in List example above, since 'T' in CompletableFuture<T> is used mostly in co-variant positions. The only methods that use it in contra-variant positions are:
>
>cf.getNow(?);
>cf.complete(?);
>cf.obtrudeValue(?);
>
What about the methods with a parameter type of:

   CompletionStage<? extends T>

such as applyToEither and acceptEither?

Paul.

Oh, I see.

That's a problem, yes. And these two methods are actually very useful in
the context of processes - waiting for 1st of two processes to finish.

So the signature can only be the following:

     CompletableFuture<ProcessHandle> completableFuture();

I hesitate to mention it, but as someone who has been frustrated by this same problem on numerous occasions I feel I must suggest that maybe... having a completableFuture method should just be dropped? A user should be able to implement it themselves fairly easily, right? And they'd be able to sidestep problems like stack size and so on by managing their own threads.


That's a good idea. If the following two methods were added to Process[Handle]:

    public class ProcessHandle {
        public ProcessHandle waitForUninterruptibly();
    }

    public class Process extends ProcessHandle {
        @Override
        public Process waitForUninterruptibly();
    }

One could get CompletableFuture(s) simply by:

        ProcessHandle ph = ...;

CompletableFuture<ProcessHandle> phf = CompletableFuture.supplyAsync(ph::waitForUninterruptibly);

        Process p = ...;

CompletableFuture<Process> pf = CompletableFuture.supplyAsync(p::waitForUninterruptibly);


Peter

Reply via email to