JEP 102 Process Updates revised API draft

Peter Levart peter.levart at gmail.com
Fri Mar 13 07:56:11 UTC 2015


...in addition, I would also try not to swallow interrupts in default 
implementation:


     public CompletableFuture<Process> onExit() {
         return CompletableFuture.supplyAsync(() -> {
             boolean interrupted = false;
             while (true) {
                 try {
                     waitFor();
                     break;
                 } catch (InterruptedException x) {
                     interrupted = true;
                 }
             }
             if (interrupted) {
                 Thread.currentThread().interrupt();
             }
             return this;
         });
     }


Peter

On 03/13/2015 08:35 AM, Peter Levart wrote:
> Hi Rogger,
>
> Now that the method has a non-throwing default implementation, what do 
> you think of the following implementation note for Process.onExit():
>
>      * @implNote
>      * The default implementation of this method employs a thread from
>      * {@link java.util.concurrent.ForkJoinPool#commonPool() common pool}
>      * to {@link #waitFor() wait} for process exit, which might 
> consume a lot
>      * of memory for thread stacks if large number of processes are 
> waited for
>      * concurrently.<p>
>      * External implementations are advised to override this method 
> and provide
>      * more efficient implementation, for example, if the 
> implementation also
>      * provides {@link #toHandle()} method, it can simply do the 
> following:
>      * <pre>{@code
>      *    public CompletableFuture<Process> onExit() {
>      *       return toHandle().onExit().thenApply(ph -> this);
>      *    }
>      * }</pre>
>      * ...which in case of internal implementation of ProcessHandle
>      * ({@link java.lang.ProcessHandle#of(long)}}), employs a more 
> efficient
>      * mechanism for waiting on process exit.
>
>
>
> Regards, Peter
>
>
> On 03/12/2015 11:33 PM, Peter Levart wrote:
>>
>>
>> On 03/12/2015 09:41 PM, Roger Riggs wrote:
>>> Hi Peter,
>>>
>>> Introducing a public Process subtype would not be a binary 
>>> compatible change;
>>> the return type of ProcessBuilder.start can not be narrowed.
>>> As you surmised, a different start method would be needed on 
>>> ProcessBuilder.
>>> Since ProcessBuilder is the preferred mechanism to created 
>>> processes, I would
>>> leave Runtime.exec alone to avoid a proliferation of similar methods.
>>>
>>> If ProcessHandle were an interface, Process would still have the 
>>> conflict over the
>>> return type of onExit() since CompletableFuture<Process> is not type 
>>> compatible
>>> with CF<ProcessHandle>.  So not quite the winning combination to 
>>> enable polymorphism.
>>>
>>> Roger
>>
>> That's right. The delegation approach with unrelated Process / 
>> ProcessHandle seems to be the most clean from API perspective.
>>
>> Regards, Peter
>>
>>>
>>>
>>> On 3/12/2015 10:38 AM, Peter Levart wrote:
>>>> On 03/12/2015 02:39 PM, Roger Riggs wrote:
>>>>> Hi,
>>>>>
>>>>> Just a thought, it might be useful to introduce a public subtype 
>>>>> of Process that is
>>>>> returned from ProcessBuilder for which the guarantees about 
>>>>> behavior could be
>>>>> tighter  (no UOEs).  It would also provide a place to document the 
>>>>> behaviors
>>>>> now spread across ProcessBuilder and Process.
>>>>>
>>>>> $.02, Roger
>>>>>
>>>>
>>>> That was my thinking too today. A Process2 or XProcess? If 
>>>> ProcessHandle was an interface this subtype could implement it 
>>>> (back to square one). I think it could be an interface if Process2 
>>>> was not publicly extendable (package-protected constructor) as it 
>>>> would not represent part of extensible API.
>>>>
>>>> Does that mean that we would need additional methods 
>>>> ProcessBuilder.start2() / Runtime.exec2() too?
>>>>
>>>> Peter
>>>>
>>
>>
>
>




More information about the core-libs-dev mailing list