-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[Process] Provide getPipes() public interface. #19559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
But this isn't portable unless I'm wrong: Windows pipes or sigchild enabled php pipes must be handled very differently. This looks like making the abstraction leak and defeating the purpose of the component. |
@nicolas-grekas Could be, but then not sure what is the correct way to expose the unix pipes. As the comment in code indicates I need to be able to use Additionally, per the discussion in #19558 I also need direct write access to input pipe to avoid delays. Alternatively, write could be handled by calling isrunning() (which triggers readwrite or pipes) after appendingInputBuffer(), but as described the current interactive input implementation is unclear how to flush the buffer. |
Useful for performing stream operations directly on the pipes.
699622e
to
ba361a1
Compare
As far as portability getPipes() returns the wrapper pipe class which will expose different features on different platforms. As such it's portable, but one would need to check the specific subclass to know if particular features are available. Having a parameter for the For now I'll just use it this way until someone can come up with an acceptable way. |
To be clear I basically need: while (true) {
$r = [$process1->getPipes()->pipes[1], $process2->getPipes()->pipes[1]];
stream_select($r, $w, $e, 1, 0);
} Noting the custom timeout. With the rest of feature provided by process which I can trigger with: $process->isRunning(); // triggers reading of pipes
$process->checkTimeout(); // can trigger exception Many moons ago, I did this with php-inotify while watching multiple files as whichever was written to first indicated completion. No need for ReactPHP or somesuch as that's the whole point of @ |
@nicolas-grekas Also what do you think of exposing processInformation? For instance if one wants to handle process termination inside a process subclass the only real place is updateStatus()
{
$running = magic();
parent::updateStatus()
if (!magic() && $running) {
// terminated
}
} I understand the concept behind only exposing the API surface one intends, but having everything private without a properly thought through flexible API just neuters an otherwise handy implementation. Any thoughts? |
So, I'm 👎 on this one: the exposed classes are About your last question, you should be able already to deal with recursivity: just add a property |
The /**
* Returns PipesInterface for underlying process.
*
* Useful for performing stream operations directly on the pipes. For
* example performing a stream_select() across multiple processes.
*
* Obviously, closing or altering pipes may cause errors.
*
* @throws LogicException In case the process is not running
*/
public function getPipes()
{
static $bind;
if (!isset($bind)) {
$getPipes = function()
{
if (!$this->isRunning()) {
throw new LogicException('Process pipes are not available while the process is not running.');
}
return $this->processPipes;
};
// The scope parameter will need to be updated if this class ends up with
// another parent in between it and Symfony Process.
$bind = Closure::bind($getPipes, $this, get_parent_class());
}
return $bind();
} The recursive check I implemented as method static, but it indeed functions. Thanks. I prefer these to having a fork/patch against proper Process. As such I imagine these pull requests can be closed |
Useful for performing stream operations directly on the pipes.