RFR 9: 8077350 Process API Updates Implementation Review
Roger Riggs
Roger.Riggs at Oracle.com
Tue May 19 13:43:17 UTC 2015
Hi Paul,
a couple of followup responses...
On 5/18/2015 5:16 PM, Paul Sandoz wrote:
>
>>>
>>> 251 /**
>>> 252 * Kills the subprocess forcibly. The subprocess represented by this
>>> 253 * {@code Process} object is forcibly terminated.
>>> 254 * Forcible process destruction is defined as the immediate termination of a
>>> 255 * process, whereas normal termination allows a process to shut down cleanly.
>>> 256 * If the process is not alive, no action is taken.
>>> 257 * <p>
>>> 258 * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
>>> 259 * {@link java.util.concurrent.CompletableFuture#complete completed}
>>> 260 * when the process has terminated.
>>> 261 *
>> insert @implSpec
>>> 262 * <p>The default implementation of this method invokes {@link #destroy}
>>> 263 * and so may not forcibly terminate the process.
>> insert @implNote
>>> 264 * Concrete implementations of this class are strongly encouraged to override
>>> 265 * this method with a compliant implementation.
>> legacy spec - move up before other @ tags
>>> 266 * Invoking this method on {@code Process} objects returned by
>>> 267 * {@link ProcessBuilder#start} and {@link Runtime#exec} forcibly terminate
>>> 268 * the process.
>>> 269 *
>>>
>>> Use @ImplNote?
>> Most of this is spec, not informational.
> Sorry i meant @implSpec, including for the "Concrete impls..." bit.
Perhaps I misunderstood the narrow scope of @implSpec.
The @implSpec is only for the specific implementation of the method
being declared.
The concrete implementations are internal subclasses are out of that scope.
...
>>>
>>> 361 * If the process is {@link #isAlive not alive} the {@link CompletableFuture}
>>> 362 * is immediately {@link java.util.concurrent.CompletableFuture#complete completed}.
>>>
>>> s/is immediately/is returned/ ?
>> The important action to be specified is that the CF is completed() immediately.
>> Potentially it could say it is completed before the CF is returned from onExit().
>>
> Yeah, that is what i was trying to get across, it returns with an already completed CF.
ok;
* If the process is not alive the CompletableFuture returned has
been completed.
>
>
>>>
>>> 406 * @return a {@code CompletableFuture<Process>} for the Process;
>>> 407 * a unique instance is returned for each call to {@code onExit}.
>>> 408 *
>>>
>>> Any need to mention about unique instances?
>> yes, since the hierarchy of the CF instances is visible to the app and it makes
>> a difference whether a unique CF is returned for each call or whether
>> the same CF is returned from each call.
> Perhaps say "Returns a new CF..." and "@return a new {@code ..." ?
ok
>
>>>
>>> 429 /**
>>> 430 * Returns a ProcessHandle for the Process.
>>> 431 *
>>>
>>> Some methods talk about "the subprocess" where as others talk about "the Process" and others "the process".
>> That variation of terminology predates this update.
> I think it's best to try and be consistent throughout the class e.g. keep with the existing term or change to consistently use a new term.
>
>
>>>
>>> 456 /**
>>> 457 * Returns a snapshot of information about the process.
>>> 458 *
>>> 459 * <p> An {@link ProcessHandle.Info} instance has various accessor methods
>>> 460 * that return information about the process, if the process is alive and
>>> 461 * the information is available, otherwise {@code null} is returned.
>>> 462 *
>>> 463 * @implSpec
>>> 464 * This implementation returns information about the process as:
>>> 465 * {@link #toHandle toHandle().info()}.
>>> 466 *
>>> 467 * @return a snapshot of information about the process; non-null
>>>
>>> Dangling "non-null". Do you mean it's can never be null or ", otherwise null if the process is not alive or such information is not available"? I suspect the former now all Info methods return Optional.
>> It is always non-null.
> Ok, so the first paragraph needs tweaking.
ok, the description of the methods of the info class are better left to
the Info class. ...
>>>
>>> 86 /**
>>> 87 * Returns the native process ID of the process. The native process ID is an
>>> 88 * identification number that the operating system assigns to the process.
>>> 89 *
>>> 90 * @return the native process ID of the process
>>> 91 * @throws UnsupportedOperationException if the implementation
>>> 92 * does not support this operation
>>> 93 */
>>> 94 long getPid();
>>>
>>> In what cases could this throw a USO if the static "of "method did not?
>> Its in an interface that might have arbitrary implementations. In a theoretical
>> Process implementation for remote processes their might not be a viable pid
>> or the access controls might be such that the PID is meaningless or restricted.
>>
> Ok, i think i get it: a call ProcessHandle.getPid obtained from ProcessHandle.of will never from a USO but other implementations of ProcessHandle might.
yes
>>>
>>> 326 * @return an {@code Optional<ProcessHandle>} for the process to be
>>> 327 * forcibly destroyed;
>>> 328 * the {@code Optional} has the value of the ProcessHandle
>>> 329 * if the request to terminate was successful, otherwise it is empty
>>> 330 * @throws IllegalStateException if the process is the current process
>>> 331 */
>>> 332 Optional<ProcessHandle> destroyForcibly();
>>>
>>> Under what cases would an empty optional be returned? e.g. if native permissions are not granted?
>> yes, but Alan's and other remarks recommend changing the return type.
>> boolean will cover case to reflect that it was not possible to request the process
>> to be destroyed without creating a confusing state of an Optional.
> Yes, that seems a better signal. What could the caller do if false is returned? not much i guess except log something.
Correct, there is not much to log unless the OS specific error returns
are exposed.
Thanks, Roger
More information about the core-libs-dev
mailing list