Config.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <?php
  2. /*
  3. *
  4. * Copyright 2018 gRPC authors.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19. namespace Grpc\Gcp;
  20. use Psr\Cache\CacheItemPoolInterface;
  21. /**
  22. * Config is used to enable the support for the channel management.
  23. */
  24. class Config
  25. {
  26. private $hostname;
  27. private $gcp_call_invoker;
  28. private $cross_script_shmem_enabled;
  29. private $supported_sapis = ['fpm-fcgi', 'cli-server'];
  30. /**
  31. * @param string $target The target API we want to manage the connection.
  32. * @param \Grpc\Gcp\ApiConfig $conf
  33. * @param CacheItemPoolInterface $cacheItemPool A pool for storing configuration and channels
  34. * cross requests within a single worker process.
  35. * @throws \RuntimeException When a failure occurs while attempting to attach to shared memory.
  36. */
  37. public function __construct($target, $conf = null, CacheItemPoolInterface $cacheItemPool = null)
  38. {
  39. if ($conf == null) {
  40. // If there is no configure file, use the default gRPC channel.
  41. $this->gcp_call_invoker = new \Grpc\DefaultCallInvoker();
  42. return;
  43. }
  44. $gcp_channel = null;
  45. $url_host = parse_url($target, PHP_URL_HOST);
  46. $this->hostname = $url_host ? $url_host : $target;
  47. $channel_pool_key = $this->hostname . '.gcp.channel.' . getmypid();
  48. if (!$cacheItemPool) {
  49. $affinity_conf = $this->parseConfObject($conf);
  50. $gcp_call_invoker = new GCPCallInvoker($affinity_conf);
  51. $this->gcp_call_invoker = $gcp_call_invoker;
  52. } else {
  53. $item = $cacheItemPool->getItem($channel_pool_key);
  54. if ($item->isHit()) {
  55. // Channel pool for the $hostname API has already created.
  56. $gcp_call_invoker = unserialize($item->get());
  57. } else {
  58. $affinity_conf = $this->parseConfObject($conf);
  59. // Create GCP channel based on the information.
  60. $gcp_call_invoker = new GCPCallInvoker($affinity_conf);
  61. }
  62. $this->gcp_call_invoker = $gcp_call_invoker;
  63. register_shutdown_function(function ($gcp_call_invoker, $cacheItemPool, $item) {
  64. // Push the current gcp_channel back into the pool when the script finishes.
  65. $item->set(serialize($gcp_call_invoker));
  66. $cacheItemPool->save($item);
  67. }, $gcp_call_invoker, $cacheItemPool, $item);
  68. }
  69. }
  70. /**
  71. * @return \Grpc\CallInvoker The call invoker to be hooked into the gRPC
  72. */
  73. public function callInvoker()
  74. {
  75. return $this->gcp_call_invoker;
  76. }
  77. /**
  78. * @return string The URI of the endpoint
  79. */
  80. public function getTarget()
  81. {
  82. return $this->channel->getTarget();
  83. }
  84. private function parseConfObject($conf_object)
  85. {
  86. $config = json_decode($conf_object->serializeToJsonString(), true);
  87. if (isset($config['channelPool'])) {
  88. $affinity_conf['channelPool'] = $config['channelPool'];
  89. }
  90. $aff_by_method = array();
  91. if (isset($config['method'])) {
  92. for ($i = 0; $i < count($config['method']); $i++) {
  93. // In proto3, if the value is default, eg 0 for int, it won't be serialized.
  94. // Thus serialized string may not have `command` if the value is default 0(BOUND).
  95. if (!array_key_exists('command', $config['method'][$i]['affinity'])) {
  96. $config['method'][$i]['affinity']['command'] = 'BOUND';
  97. }
  98. $aff_by_method[$config['method'][$i]['name'][0]] = $config['method'][$i]['affinity'];
  99. }
  100. }
  101. $affinity_conf['affinity_by_method'] = $aff_by_method;
  102. return $affinity_conf;
  103. }
  104. }