|
1 | 1 | <?php
|
2 | 2 |
|
3 | 3 | /*
|
4 |
| - * Copyright 2011 Facebook, Inc. |
| 4 | + * Copyright 2012 Facebook, Inc. |
5 | 5 | *
|
6 | 6 | * Licensed under the Apache License, Version 2.0 (the "License");
|
7 | 7 | * you may not use this file except in compliance with the License.
|
@@ -137,33 +137,43 @@ private function establishConnection() {
|
137 | 137 | 'database' => $database,
|
138 | 138 | ));
|
139 | 139 |
|
140 |
| - try { |
141 |
| - $conn = @mysql_connect( |
142 |
| - $host, |
143 |
| - $user, |
144 |
| - $this->getConfiguration('pass'), |
145 |
| - $new_link = true, |
146 |
| - $flags = 0); |
147 |
| - |
148 |
| - if (!$conn) { |
149 |
| - $errno = mysql_errno(); |
150 |
| - $error = mysql_error(); |
151 |
| - throw new AphrontQueryConnectionException( |
152 |
| - "Attempt to connect to {$user}@{$host} failed with error #{$errno}: ". |
153 |
| - "{$error}."); |
154 |
| - } |
| 140 | + $retries = max(1, PhabricatorEnv::getEnvConfig('mysql.connection-retries')); |
| 141 | + while ($retries--) { |
| 142 | + try { |
| 143 | + $conn = @mysql_connect( |
| 144 | + $host, |
| 145 | + $user, |
| 146 | + $this->getConfiguration('pass'), |
| 147 | + $new_link = true, |
| 148 | + $flags = 0); |
| 149 | + |
| 150 | + if (!$conn) { |
| 151 | + $errno = mysql_errno(); |
| 152 | + $error = mysql_error(); |
| 153 | + throw new AphrontQueryConnectionException( |
| 154 | + "Attempt to connect to {$user}@{$host} failed with error ". |
| 155 | + "#{$errno}: {$error}.", $errno); |
| 156 | + } |
155 | 157 |
|
156 |
| - if ($database !== null) { |
157 |
| - $ret = @mysql_select_db($database, $conn); |
158 |
| - if (!$ret) { |
159 |
| - $this->throwQueryException($conn); |
| 158 | + if ($database !== null) { |
| 159 | + $ret = @mysql_select_db($database, $conn); |
| 160 | + if (!$ret) { |
| 161 | + $this->throwQueryException($conn); |
| 162 | + } |
160 | 163 | }
|
161 |
| - } |
162 | 164 |
|
163 |
| - $profiler->endServiceCall($call_id, array()); |
164 |
| - } catch (Exception $ex) { |
165 |
| - $profiler->endServiceCall($call_id, array()); |
166 |
| - throw $ex; |
| 165 | + $profiler->endServiceCall($call_id, array()); |
| 166 | + break; |
| 167 | + } catch (Exception $ex) { |
| 168 | + if ($retries && $ex->getCode() == 2003) { |
| 169 | + $class = get_class($ex); |
| 170 | + $message = $ex->getMessage(); |
| 171 | + phlog("Retrying ({$retries}) after {$class}: {$message}"); |
| 172 | + } else { |
| 173 | + $profiler->endServiceCall($call_id, array()); |
| 174 | + throw $ex; |
| 175 | + } |
| 176 | + } |
167 | 177 | }
|
168 | 178 |
|
169 | 179 | self::$connectionCache[$key] = $conn;
|
@@ -203,7 +213,7 @@ public function selectAllResults() {
|
203 | 213 |
|
204 | 214 | public function executeRawQuery($raw_query) {
|
205 | 215 | $this->lastResult = null;
|
206 |
| - $retries = 3; |
| 216 | + $retries = max(1, PhabricatorEnv::getEnvConfig('mysql.connection-retries')); |
207 | 217 | while ($retries--) {
|
208 | 218 | try {
|
209 | 219 | $this->requireConnection();
|
@@ -242,6 +252,9 @@ public function executeRawQuery($raw_query) {
|
242 | 252 | if ($this->isInsideTransaction()) {
|
243 | 253 | throw $ex;
|
244 | 254 | }
|
| 255 | + $class = get_class($ex); |
| 256 | + $message = $ex->getMessage(); |
| 257 | + phlog("Retrying ({$retries}) after {$class}: {$message}"); |
245 | 258 | $this->closeConnection();
|
246 | 259 | }
|
247 | 260 | }
|
|
0 commit comments