JEP 102 Process Updates revised API draft

Roger Riggs Roger.Riggs at Oracle.com
Tue Feb 10 19:31:28 UTC 2015


Hi Peter,

On 2/10/2015 6:35 AM, Peter Levart wrote:
> On 02/10/2015 12:25 AM, Roger Riggs wrote:
>> Hi,
>>
>> After a protracted absence from working on JEP 102, the updated API 
>> draft
>> provides access to process hierarchies and individual process 
>> information;
>> as permitted by the OS. The relationship between Process and 
>> ProcessHandle
>> is clarified and the security model validated.
>>
>> Both Processes and ProcessHandles can be monitored using 
>> CompletableFuture
>> for termination and to trigger additional actions on Process exit.
>> Information about processes includes the total cputime, starttime, user,
>> executable, and arguments.
>>
>> Please review and comment:
>>    http://cr.openjdk.java.net/~rriggs/ph-apidraft/
>>
>> Thanks, Roger
>>
>>
>>
>>
> Hi Roger,
>
> Great to see progress on this.
>
> Here are my comments:
>
> ProcessHandle.{allProcesses,allChildren,children} return 
> Stream<ProcessHandle>. This is convenient if one wants to use Stream 
> API, but a little more inconvenient and perhaps with additional 
> overhead if one doesn't. Since all those methods return a "snapshot", 
> I can imagine that internally, there is a collection built from this 
> snapshot. So it would be most appropriate to return a 
> List<ProcessHandle>. One can always continue the expression by 
> appending .stream()..., but on the other hand if one wants to 
> .collect(toList()), additional copying is introduced.
I've been pulled both ways by various folks here also.
Both Streams and Collections are easily converted to the other.
The internal snapshot is an array of int pid's;  with the Stream, the 
creation of ProcessHandles can
be delayed until they are needed, if they are needed.
>
> ProcessHandle.completableFuture().cancel(true) forcibly destorys 
> (destroyForcibly()) the process *and* vice versa: destory[Forcibly]() 
> cancels the CompletableFuture. I don't know if this is the best way - 
> can't decide yet. In particular, in the implementation it would be 
> hard to achieve the atommicity of both destroying the process and 
> canceling the future. Races are inevitable.
Atomicity is provided by CompletableFuture, it handles the atomicity of 
updating its state.
If cancelled, there is no useful information or synchronization is 
needed from the (dieing) Process;
the CompletableFuture state/status is cancelled.
> So it would be better to think of a process (and a ProcessHandle 
> representing it) as the 1st stage in the processing pipeline, where 
> ProcessHandle.completableFuture() is it's dependent stage which tracks 
> real changes of the process. Which means the behaviour would be 
> something like the following:
>
> - ProcessHandle.destroy[Forcibly]() triggers destruction of the 
> process which in turn (when successful) triggers completion of 
> CompletableFuture, exceptionally with CompletionException, wrapping 
> the exception indicating the destruction of the process 
> (ProcessDestroyedException?).
Maybe thinking along the similar lines; Process and Future are loosely 
coupled;
A process exiting, regardless of whether  it was killed by some entity 
in the system
or the Java API should complete the Future.
For a Process, the exitStatus is available and could be used to modify 
the normal vs exceptional completion.
But for an arbitrary ProcessHandle, the process may not have been 
spawned by this process;
in that case the exit status is not available (see previous long 
discussions about reaping).
Also, the exit status may not be a reliable indication of success vs 
failure of the process.
So the best that can be reported is that the Process is terminated and 
the Future is completed (normally).

>
> - ProcessHandle.completableFuture().cancel(true/false) just cancels 
> the CompletableFuture and does not do anything to the process itself.

My model was that the CompletableFuture from ProcessHandle is a proxy 
for the process itself.
It is an abstraction for the Process that is independent of the 
implementation (as a Process).
It looks just like any other stage in the tree of CompletionStages.
The application that spawns the Process can control what it exposes as 
the CompletableFuture
it can expose the root or create another Completable future to hang 
other operations on.

>
> In that variant, then perhaps it would be more appropriate for 
> ProcessHandle.completableFuture() to be a "factory" for 
> CompletableFuture(s) so that each call would return new independent 
> instance.
>
> What do you think?

I'm not sure which model is more useful to the application/library.
The implementation may be simpler if it only has to keep track of a 
single CompletableFuture
instead of a set but decoupling may be simpler to model.

Thanks, Roger
>
> Regards, Peter
>




More information about the core-libs-dev mailing list