diff --git a/src/phage/agent/PhagePHPAgent.php b/src/phage/agent/PhagePHPAgent.php --- a/src/phage/agent/PhagePHPAgent.php +++ b/src/phage/agent/PhagePHPAgent.php @@ -17,10 +17,14 @@ $iterator->setUpdateInterval(0.050); foreach ($iterator as $key => $future) { if ($future === null) { + foreach ($this->exec as $read_key => $read_future) { + $this->readFuture($read_key, $read_future); + } + break; + } else { + $this->resolveFuture($key, $future); } - $this->resolveFuture($key, $future); - break; } } else { PhutilChannel::waitForAny(array($this->getMaster())); @@ -67,6 +71,8 @@ $cmd = $spec['command']; $future = new ExecFuture('%C', $cmd); + $future->isReady(); + $this->exec[$key] = $future; break; case 'EXIT': @@ -75,7 +81,34 @@ } } - private function resolveFuture($key, Future $future) { + private function readFuture($key, ExecFuture $future) { + $master = $this->getMaster(); + + list($stdout, $stderr) = $future->read(); + $future->discardBuffers(); + + if (strlen($stdout)) { + $master->write( + array( + 'type' => 'TEXT', + 'key' => $key, + 'kind' => 'stdout', + 'text' => $stdout, + )); + } + + if (strlen($stderr)) { + $master->write( + array( + 'type' => 'TEXT', + 'key' => $key, + 'kind' => 'stderr', + 'text' => $stderr, + )); + } + } + + private function resolveFuture($key, ExecFuture $future) { $result = $future->resolve(); $master = $this->getMaster(); @@ -87,6 +120,7 @@ 'stdout' => $result[1], 'stderr' => $result[2], )); + unset($this->exec[$key]); } diff --git a/src/phage/bootloader/PhagePHPAgentBootloader.php b/src/phage/bootloader/PhagePHPAgentBootloader.php --- a/src/phage/bootloader/PhagePHPAgentBootloader.php +++ b/src/phage/bootloader/PhagePHPAgentBootloader.php @@ -63,7 +63,12 @@ foreach ($files as $file) { $main_sequence->addFile($root.'/'.$file); } - $main_sequence->addText('id(new PhagePHPAgent($I))->execute();'); + + // NOTE: If we use id() here, we don't get a stack trace out of it when + // we call a nonexistent method from inside "execute()"? Not exactly sure + // what's going on here, but just sweep it under the rug for now. + + $main_sequence->addText('$A = new PhagePHPAgent($I); $A->execute();'); $main_length = strlen($main_sequence->toString()); $boot_sequence = new PhutilBallOfPHP(); @@ -77,6 +82,7 @@ } $buffer .= $data; } + eval($buffer);'; $boot_sequence->addText($boot); $boot_length = strlen($boot_sequence->toString());