CoRefPool.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. abstract class CoRefPool
  3. {
  4. private $mMaxClient;
  5. private $mFreeClients;
  6. private $mUsingClients;
  7. private $mSuspendCIDS;
  8. private $mStop;
  9. public function __construct($max_clients)
  10. {
  11. $this->mMaxClient = $max_clients;
  12. $this->mUsingClients = [];
  13. $this->mFreeClients = [];
  14. $this->mSuspendCIDS = [];
  15. $this->mStop = false;
  16. }
  17. public function get($cid)
  18. {
  19. if(array_key_exists($cid,$this->mUsingClients)) {
  20. $this->mUsingClients[$cid]['ref_count'] += 1;
  21. return $this->mUsingClients[$cid]['client'];
  22. }
  23. if(!empty($this->mFreeClients)) {
  24. $client = $this->mFreeClients[0];
  25. unset($this->mFreeClients[0]);
  26. $this->mFreeClients = array_values($this->mFreeClients);
  27. $this->mUsingClients[$cid] = ['client' => $client, 'ref_count' => 1,'ifTransacting' => false];
  28. }
  29. elseif(count($this->mUsingClients) < $this->mMaxClient) {
  30. $client = $this->create_client();
  31. $this->mUsingClients[$cid] = ['client' => $client, 'ref_count' => 1,'ifTransacting' => false];
  32. }
  33. else {
  34. $this->mSuspendCIDS[] = Co::getCid();
  35. Co::suspend();
  36. $client = $this->mFreeClients[0];
  37. unset($this->mFreeClients[0]);
  38. $this->mFreeClients = array_values($this->mFreeClients);
  39. $this->mUsingClients[$cid] = ['client' => $client, 'ref_count' => 1,'ifTransacting' => false];
  40. }
  41. $count = count($this->mUsingClients);
  42. Log::record("get mUsingCount={$count}",Log::DEBUG);
  43. return $client;
  44. }
  45. public function find($cid)
  46. {
  47. if(array_key_exists($cid,$this->mUsingClients)) {
  48. return $this->mUsingClients[$cid]['client'];
  49. } else {
  50. Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG);
  51. throw new Exception("cannot find mysqli cid={$cid} client");
  52. }
  53. }
  54. public function reset($cid,$client)
  55. {
  56. if(array_key_exists($cid,$this->mUsingClients)) {
  57. return $this->mUsingClients[$cid]['client'] = $client;
  58. } else {
  59. Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG);
  60. throw new Exception("cannot find mysqli cid={$cid} client");
  61. }
  62. }
  63. public function transaction($cid)
  64. {
  65. if(array_key_exists($cid,$this->mUsingClients)) {
  66. return $this->mUsingClients[$cid]['ifTransacting'];
  67. } else {
  68. Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG);
  69. throw new Exception("cannot find mysqli cid={$cid} client");
  70. }
  71. }
  72. public function commit($cid)
  73. {
  74. if(array_key_exists($cid,$this->mUsingClients)) {
  75. return $this->mUsingClients[$cid]['ifTransacting'] = false;
  76. } else {
  77. Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG);
  78. throw new Exception("cannot find mysqli cid={$cid} client");
  79. }
  80. }
  81. public function rollback($cid)
  82. {
  83. if(array_key_exists($cid,$this->mUsingClients)) {
  84. return $this->mUsingClients[$cid]['ifTransacting'] = false;
  85. } else {
  86. Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG);
  87. throw new Exception("cannot find mysqli cid={$cid} client");
  88. }
  89. }
  90. public function put($cid)
  91. {
  92. Log::record("CoRefPool put cid={$cid}",Log::DEBUG);
  93. if(array_key_exists($cid,$this->mUsingClients))
  94. {
  95. $this->mUsingClients[$cid]['ref_count'] -= 1;
  96. $refcount = $this->mUsingClients[$cid]['ref_count'];
  97. if($refcount == 0)
  98. {
  99. $client = $this->mUsingClients[$cid]['client'];
  100. unset($this->mUsingClients[$cid]);
  101. $this->mFreeClients[] = $client;
  102. $suspend_cid = $this->getSuspend();
  103. if($suspend_cid > 0) {
  104. Co::resume($suspend_cid);
  105. }
  106. Log::record("CoRefPool put cid={$cid} suspend_cid={$suspend_cid} refcount={$refcount}",Log::DEBUG);
  107. }
  108. else {
  109. Log::record("CoRefPool put cid={$cid} refcount={$refcount}",Log::DEBUG);
  110. }
  111. }
  112. else {
  113. Log::record(__METHOD__ . " cannot find mysqli cid={$cid} client",Log::DEBUG);
  114. throw new Exception("cannot find mysqli cid={$cid} client");
  115. }
  116. }
  117. private function getSuspend()
  118. {
  119. if (empty($this->mSuspendCIDS)) {
  120. return 0;
  121. } else {
  122. $cid = $this->mSuspendCIDS[0];
  123. unset($this->mSuspendCIDS[0]);
  124. $this->mSuspendCIDS = array_values($this->mSuspendCIDS);
  125. return $cid;
  126. }
  127. }
  128. public function stoped() {
  129. return $this->mStop;
  130. }
  131. public function stop() {
  132. $this->mStop = true;
  133. }
  134. abstract public function create_client();
  135. }