panther icon indicating copy to clipboard operation
panther copied to clipboard

Run multiple instances in parallel?

Open AndriusCTR opened this issue 5 years ago • 6 comments

Hello,

Is it possible to run multiple Panther (using headless chrome) in parallel?

If I try to run same script from the second terminal i get this error:

"PHP Fatal error: Uncaught RuntimeException: The port 9515 is already in use"

What are the ways to run multiple instances at once?

AndriusCTR avatar Apr 16 '19 18:04 AndriusCTR

The browser manager accept a port option to configure the port on which it will communicate. 9515 is the default value. If you want to run multiple instance in parallel on the same machine, you will need to use different ports for each instance of the browser manager.

stof avatar Apr 17 '19 11:04 stof

The browser manager accept a port option to configure the port on which it will communicate. 9515 is the default value. If you want to run multiple instance in parallel on the same machine, you will need to use different ports for each instance of the browser manager.

Thanks. Is there an example somwhere how to set custom port?

I see 'PANTHER_WEB_SERVER_PORT' environment variable. Should this one be used? How one sets it within php script?

AndriusCTR avatar Apr 17 '19 16:04 AndriusCTR

I've looked into this and unfortunately, there are no ways to provide options when creating the chrome client to override the port.

https://github.com/symfony/panther/blob/master/src/PantherTestCaseTrait.php#L137

From looking at the source of ChromeManager, there's also no environment variable to override the port:

https://github.com/symfony/panther/blob/master/src/ProcessManager/ChromeManager.php

The only option that would work at the moment, that I can think of, would be to override createPantherClient either in your own existing base TestCase class, or create one to do just that.

navitronic avatar Apr 17 '19 23:04 navitronic

It would be nice to find a fix to be able to test apps using Mercure.

dunglas avatar May 09 '19 10:05 dunglas

Please read the file: vendor/symfony/panther/src/ProcessManager/ChromeManager.php You can assign the port by assign the $options.

public function __construct(?string $chromeDriverBinary = null, ?array $arguments = null, array $options = [])
    {
        $this->options = array_merge($this->getDefaultOptions(), $options);
        $this->process = new Process([$chromeDriverBinary ?: $this->findChromeDriverBinary(), '--port='.$this->options['port']], null, null, null, null);
        $this->arguments = $arguments ?? $this->getDefaultArguments();
    }
private function getDefaultOptions(): array
    {
        return [
            'scheme' => 'http',
            'host' => '127.0.0.1',
            'port' => 9515,
            'path' => '/status',
            'capabilities' => [],
        ];
    }

You just assign a new array to overwrite the $options. For example,

$options = [
'port' => get_unused_tcp_port()
];

and assign the $options to the constructor and it works. Ps. You need to write the get_unused_tcp_port() function by yourself.

woei66 avatar Apr 14 '21 09:04 woei66


function get_unused_tcp_port() {
    $address = '127.0.0.1';
// Create a new socket
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Bind the source address
    socket_bind($sock, $address);
    socket_getsockname($sock, $address, $port);
    #echo $port;
    socket_close($sock);
    return $port;
}

woei66 avatar Jul 02 '21 04:07 woei66