diff --git a/README.md b/README.md index 8f1cc55a..2c291b5e 100644 --- a/README.md +++ b/README.md @@ -26,15 +26,19 @@ use Tarantool\Client\Packer\PurePacker; $conn = new StreamConnection(); // or -// $conn = new StreamConnection('tcp://127.0.0.1:3301'); -// $conn = new StreamConnection('tcp://127.0.0.1:3301', ['socket_timeout' => 5.0, 'connect_timeout' => 5.0]); +// $conn = new StreamConnection('tcp://127.0.0.1:3301', [ +// 'socket_timeout' => 5.0, +// 'connect_timeout' => 5.0, +// 'tcp_nodelay' => true, +// ]); +// or // $conn = new StreamConnection('unix:///tmp/tarantool_instance.sock'); $client = new Client($conn, new PurePacker()); // or // $client = new Client($conn, new PeclPacker()); -// If authentication credentials required +// if authentication credentials are required // $client->authenticate('username', 'userpass'); $space = $client->getSpace('my_space'); diff --git a/src/Connection/StreamConnection.php b/src/Connection/StreamConnection.php index aae88c93..77910654 100644 --- a/src/Connection/StreamConnection.php +++ b/src/Connection/StreamConnection.php @@ -40,6 +40,15 @@ public function open() $this->stream = $stream; stream_set_timeout($this->stream, $this->options['socket_timeout']); + // TODO + // use stream_context_create() for php 7.1+ + // https://github.com/php/php-src/blob/6053987bc27e8dede37f437193a5cad448f99bce/ext/standard/tests/streams/stream_context_tcp_nodelay.phpt + + if (isset($this->options['tcp_nodelay']) && function_exists('socket_import_stream')) { + $socket = socket_import_stream($this->stream); + socket_set_option($socket, SOL_TCP, TCP_NODELAY, (int) $this->options['tcp_nodelay']); + } + $greeting = $this->read(IProto::GREETING_SIZE, 'Unable to read greeting.'); return IProto::parseGreeting($greeting); diff --git a/tests/Integration/ConnectionTest.php b/tests/Integration/ConnectionTest.php index 7906a837..ea6570ac 100644 --- a/tests/Integration/ConnectionTest.php +++ b/tests/Integration/ConnectionTest.php @@ -210,6 +210,50 @@ public function testReadLargeResponse() $this->assertSame($data, $result->getData()[0]); } + /** + * @requires extension sockets + * + * @group tcp_only + * @group pure_only + */ + public function testTcpNoDelayEnabled() + { + $clientBuilder = ClientBuilder::createFromEnv(); + $clientBuilder->setConnectionOptions(['tcp_nodelay' => true]); + + $client = $clientBuilder->build(); + $client->ping(); + + $conn = $client->getConnection(); + $prop = (new \ReflectionObject($conn))->getProperty('stream'); + $prop->setAccessible(true); + + $socket = socket_import_stream($prop->getValue($conn)); + $this->assertSame(1, socket_get_option($socket, SOL_TCP, TCP_NODELAY)); + } + + /** + * @requires extension sockets + * + * @group tcp_only + * @group pure_only + */ + public function testTcpNoDelayDisabled() + { + $clientBuilder = ClientBuilder::createFromEnv(); + $clientBuilder->setConnectionOptions(['tcp_nodelay' => false]); + + $client = $clientBuilder->build(); + $client->ping(); + + $conn = $client->getConnection(); + $prop = (new \ReflectionObject($conn))->getProperty('stream'); + $prop->setAccessible(true); + + $socket = socket_import_stream($prop->getValue($conn)); + $this->assertSame(0, socket_get_option($socket, SOL_TCP, TCP_NODELAY)); + } + /** * @dataProvider \Tarantool\Client\Tests\GreetingDataProvider::provideGreetingsWithInvalidServerName */