getPersistentList(); $channel_clean_persistent->cleanPersistentList(); } public function waitUntilNotIdle($channel) { for ($i = 0; $i < 10; $i++) { $now = Grpc\Timeval::now(); $deadline = $now->add(new Grpc\Timeval(1000)); if ($channel->watchConnectivityState(GRPC\CHANNEL_IDLE, $deadline)) { return true; } } $this->assertTrue(false); } public function assertConnecting($state) { $this->assertTrue($state == GRPC\CHANNEL_CONNECTING || $state == GRPC\CHANNEL_TRANSIENT_FAILURE); } public function testInitHelper() { // PersistentList is not empty at the beginning of the tests // because phpunit will cache the channels created by other test // files. } public function testChannelNotPersist() { $this->channel1 = new Grpc\Channel('localhost:1', ['force_new' => true]); $channel1_info = $this->channel1->getChannelInfo(); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals($channel1_info['target'], 'localhost:1'); $this->assertEquals($channel1_info['ref_count'], 1); $this->assertEquals($channel1_info['connectivity_status'], GRPC\CHANNEL_IDLE); $this->assertEquals(count($plist_info), 0); $this->channel1->close(); } public function testPersistentChannelCreateOneChannel() { $this->channel1 = new Grpc\Channel('localhost:1', []); $channel1_info = $this->channel1->getChannelInfo(); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals($channel1_info['target'], 'localhost:1'); $this->assertEquals($channel1_info['ref_count'], 2); $this->assertEquals($channel1_info['connectivity_status'], GRPC\CHANNEL_IDLE); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertEquals(count($plist_info), 1); $this->channel1->close(); } public function testPersistentChannelCreateMultipleChannels() { $this->channel1 = new Grpc\Channel('localhost:1', []); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(count($plist_info), 1); $this->channel2 = new Grpc\Channel('localhost:2', []); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(count($plist_info), 2); $this->channel3 = new Grpc\Channel('localhost:3', []); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(count($plist_info), 3); } public function testPersistentChannelStatusChange() { $this->channel1 = new Grpc\Channel('localhost:4', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals($channel1_info['connectivity_status'], GRPC\CHANNEL_IDLE); $this->channel1->getConnectivityState(true); $this->waitUntilNotIdle($this->channel1); $channel1_info = $this->channel1->getChannelInfo(); $this->assertConnecting($channel1_info['connectivity_status']); $this->channel1->close(); } public function testPersistentChannelCloseChannel() { $this->channel1 = new Grpc\Channel('localhost:1', []); $this->channel2 = new Grpc\Channel('localhost:1', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals($channel1_info['ref_count'], 3); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals($plist_info[$channel1_info['key']]['ref_count'], 3); $this->channel1->close(); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals($plist_info[$channel1_info['key']]['ref_count'], 2); $this->channel2->close(); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals($plist_info[$channel1_info['key']]['ref_count'], 1); } public function testPersistentChannelSameTarget() { $this->channel1 = new Grpc\Channel('localhost:1', []); $this->channel2 = new Grpc\Channel('localhost:1', []); $plist = $this->channel2->getPersistentList(); $channel1_info = $this->channel1->getChannelInfo(); $channel2_info = $this->channel2->getChannelInfo(); // $channel1 and $channel2 shares the same channel, thus only 1 // channel should be in the persistent list. $this->assertEquals($channel1_info['key'], $channel2_info['key']); $this->assertArrayHasKey($channel1_info['key'], $plist); $this->assertEquals(count($plist), 1); $this->channel1->close(); $this->channel2->close(); } public function testPersistentChannelDifferentTarget() { $this->channel1 = new Grpc\Channel('localhost:1', []); $channel1_info = $this->channel1->getChannelInfo(); $this->channel2 = new Grpc\Channel('localhost:2', []); $channel2_info = $this->channel1->getChannelInfo(); $plist_info = $this->channel1->getPersistentList(); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertArrayHasKey($channel2_info['key'], $plist_info); $this->assertEquals($plist_info[$channel1_info['key']]['ref_count'], 2); $this->assertEquals($plist_info[$channel2_info['key']]['ref_count'], 2); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(count($plist_info), 2); $this->channel1->close(); $this->channel2->close(); } /** * @expectedException RuntimeException * @expectedExceptionMessage startBatch Error. Channel is closed */ public function testPersistentChannelSharedChannelClose() { // same underlying channel $this->channel1 = new Grpc\Channel('localhost:10001', [ "grpc_target_persist_bound" => 2, ]); $this->channel2 = new Grpc\Channel('localhost:10001', []); $this->server = new Grpc\Server([]); $this->port = $this->server->addHttp2Port('localhost:10001'); // channel2 can still be use $state = $this->channel2->getConnectivityState(); $this->assertEquals(GRPC\CHANNEL_IDLE, $state); $call1 = new Grpc\Call($this->channel1, '/foo', Grpc\Timeval::infFuture()); $call2 = new Grpc\Call($this->channel2, '/foo', Grpc\Timeval::infFuture()); $call3 = new Grpc\Call($this->channel1, '/foo', Grpc\Timeval::infFuture()); $call4 = new Grpc\Call($this->channel2, '/foo', Grpc\Timeval::infFuture()); $batch = [ Grpc\OP_SEND_INITIAL_METADATA => [], ]; $result = $call1->startBatch($batch); $this->assertTrue($result->send_metadata); $result = $call2->startBatch($batch); $this->assertTrue($result->send_metadata); $this->channel1->close(); // After closing channel1, channel2 can still be use $result = $call4->startBatch($batch); $this->assertTrue($result->send_metadata); // channel 1 is closed, it will throw an exception. $result = $call3->startBatch($batch); } public function testPersistentChannelTargetDefaultUpperBound() { $this->channel1 = new Grpc\Channel('localhost:10002', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals($channel1_info['target_upper_bound'], 1); $this->assertEquals($channel1_info['target_current_size'], 1); } public function testPersistentChannelTargetUpperBoundZero() { $this->channel1 = new Grpc\Channel('localhost:10002', [ "grpc_target_persist_bound" => 0, ]); // channel1 will not be persisted. $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals($channel1_info['target_upper_bound'], 0); $this->assertEquals($channel1_info['target_current_size'], 0); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(0, count($plist_info)); } public function testPersistentChannelTargetUpperBoundNotZero() { $this->channel1 = new Grpc\Channel('localhost:10003', [ "grpc_target_persist_bound" => 3, ]); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals($channel1_info['target_upper_bound'], 3); $this->assertEquals($channel1_info['target_current_size'], 1); // The upper bound should not be changed $this->channel2 = new Grpc\Channel('localhost:10003', []); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals($channel2_info['target_upper_bound'], 3); $this->assertEquals($channel2_info['target_current_size'], 1); // The upper bound should not be changed $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel3 = new Grpc\Channel('localhost:10003', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); $this->assertEquals($channel3_info['target_upper_bound'], 3); $this->assertEquals($channel3_info['target_current_size'], 2); // The upper bound should not be changed $this->channel4 = new Grpc\Channel('localhost:10003', [ "grpc_target_persist_bound" => 5, ]); $channel4_info = $this->channel4->getChannelInfo(); $this->assertEquals($channel4_info['target_upper_bound'], 5); $this->assertEquals($channel4_info['target_current_size'], 2); } public function testPersistentChannelDefaultOutBound1() { $this->channel1 = new Grpc\Channel('localhost:10004', []); // Make channel1 not IDLE. $this->channel1->getConnectivityState(true); $this->waitUntilNotIdle($this->channel1); $channel1_info = $this->channel1->getChannelInfo(); $this->assertConnecting($channel1_info['connectivity_status']); // Since channel1 is CONNECTING, channel 2 will not be persisted $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10004', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); // By default, target 'localhost:10011' only persist one channel. // Since channel1 is not Idle channel2 will not be persisted. $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(1, count($plist_info)); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertArrayNotHasKey($channel2_info['key'], $plist_info); } public function testPersistentChannelDefaultOutBound2() { $this->channel1 = new Grpc\Channel('localhost:10005', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel1_info['connectivity_status']); // Although channel1 is IDLE, channel1 still has reference to the underline // gRPC channel. channel2 will not be persisted $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10005', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); // By default, target 'localhost:10011' only persist one channel. // Since channel1 Idle, channel2 will be persisted. $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(1, count($plist_info)); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertArrayNotHasKey($channel2_info['key'], $plist_info); } public function testPersistentChannelDefaultOutBound3() { $this->channel1 = new Grpc\Channel('localhost:10006', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel1_info['connectivity_status']); $this->channel1->close(); // channel1 is closed, no reference holds to the underline channel. // channel2 can be persisted. $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10006', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); // By default, target 'localhost:10011' only persist one channel. // Since channel1 Idle, channel2 will be persisted. $plist_info = $this->channel2->getPersistentList(); $this->assertEquals(1, count($plist_info)); $this->assertArrayHasKey($channel2_info['key'], $plist_info); $this->assertArrayNotHasKey($channel1_info['key'], $plist_info); } public function testPersistentChannelTwoUpperBound() { $this->channel1 = new Grpc\Channel('localhost:10007', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel1_info['connectivity_status']); // Since channel1 is IDLE, channel 1 will be deleted $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10007', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(2, count($plist_info)); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertArrayHasKey($channel2_info['key'], $plist_info); } public function testPersistentChannelTwoUpperBoundOutBound1() { $this->channel1 = new Grpc\Channel('localhost:10011', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10011', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); // Close channel1, so that new channel can be persisted. $this->channel1->close(); $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); $this->channel3 = new Grpc\Channel('localhost:10011', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(2, count($plist_info)); $this->assertArrayNotHasKey($channel1_info['key'], $plist_info); $this->assertArrayHasKey($channel2_info['key'], $plist_info); $this->assertArrayHasKey($channel3_info['key'], $plist_info); } public function testPersistentChannelTwoUpperBoundOutBound2() { $this->channel1 = new Grpc\Channel('localhost:10012', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10012', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); // Close channel2, so that new channel can be persisted. $this->channel2->close(); $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); $this->channel3 = new Grpc\Channel('localhost:10012', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(2, count($plist_info)); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertArrayNotHasKey($channel2_info['key'], $plist_info); $this->assertArrayHasKey($channel3_info['key'], $plist_info); } public function testPersistentChannelTwoUpperBoundOutBound3() { $this->channel1 = new Grpc\Channel('localhost:10013', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10013', ['credentials' => $channel_credentials]); $this->channel2->getConnectivityState(true); $this->waitUntilNotIdle($this->channel2); $channel2_info = $this->channel2->getChannelInfo(); $this->assertConnecting($channel2_info['connectivity_status']); // Only one channel will be deleted $this->channel1->close(); $this->channel2->close(); $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); $this->channel3 = new Grpc\Channel('localhost:10013', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); // Only the Idle Channel will be deleted $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(2, count($plist_info)); $this->assertArrayNotHasKey($channel1_info['key'], $plist_info); $this->assertArrayHasKey($channel2_info['key'], $plist_info); $this->assertArrayHasKey($channel3_info['key'], $plist_info); } public function testPersistentChannelTwoUpperBoundOutBound4() { $this->channel1 = new Grpc\Channel('localhost:10014', [ "grpc_target_persist_bound" => 2, ]); $this->channel1->getConnectivityState(true); $this->waitUntilNotIdle($this->channel1); $channel1_info = $this->channel1->getChannelInfo(); $this->assertConnecting($channel1_info['connectivity_status']); $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); $this->channel2 = new Grpc\Channel('localhost:10014', ['credentials' => $channel_credentials]); $this->channel2->getConnectivityState(true); $this->waitUntilNotIdle($this->channel2); $channel2_info = $this->channel2->getChannelInfo(); $this->assertConnecting($channel2_info['connectivity_status']); $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); $this->channel3 = new Grpc\Channel('localhost:10014', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); // Channel3 will not be persisted $plist_info = $this->channel1->getPersistentList(); $this->assertEquals(2, count($plist_info)); $this->assertArrayHasKey($channel1_info['key'], $plist_info); $this->assertArrayHasKey($channel2_info['key'], $plist_info); $this->assertArrayNotHasKey($channel3_info['key'], $plist_info); } }