Skip to content

Commit 030efec

Browse files
committed
Don't trust server status unless the same value is observed across 3 consecutive polling intervals
1 parent e7152cc commit 030efec

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

src/corelib/Providers/Rackspace/CloudServersProvider.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,19 @@ public Server WaitForServerState(string serverId, ServerState[] expectedStates,
329329

330330
var serverDetails = GetDetails(serverId, region, identity);
331331

332+
/*
333+
* The polling implementation uses triple-checked polling to work around a known bug in Cloud
334+
* Servers status reporting. Occasionally, for a brief period of time during an asynchronous
335+
* server operation, the service will return incorrect values in all of the status fields.
336+
* Polling multiple times allows this SDK to provide reliable wait operations even when the
337+
* server returns unreliable values.
338+
*/
339+
340+
Func<bool> exitCondition = () => serverDetails.TaskState == null && (expectedStates.Contains(serverDetails.Status) || errorStates.Contains(serverDetails.Status));
332341
int count = 0;
333342
int currentProgress = -1;
334-
while ((serverDetails.TaskState != null || (!expectedStates.Contains(serverDetails.Status) && !errorStates.Contains(serverDetails.Status))) && count < refreshCount)
343+
int exitCount = exitCondition() ? 1 : 0;
344+
while (exitCount < 3 && count < refreshCount)
335345
{
336346
if (progressUpdatedCallback != null)
337347
{
@@ -345,6 +355,10 @@ public Server WaitForServerState(string serverId, ServerState[] expectedStates,
345355
Thread.Sleep(refreshDelay ?? TimeSpan.FromMilliseconds(2400));
346356
serverDetails = GetDetails(serverId, region, identity);
347357
count++;
358+
if (exitCondition())
359+
exitCount++;
360+
else
361+
exitCount = 0;
348362
}
349363

350364
if (errorStates.Contains(serverDetails.Status))

0 commit comments

Comments
 (0)