in src/library/Connect/KubernetesRemoteEnvironmentManager.cs [913:976]
private async Task<bool> _WaitForPodStoppedAsync(V1Pod pod, CancellationToken cancellationToken)
{
var namespaceName = pod.Metadata.NamespaceProperty;
var podName = pod.Metadata.Name;
while (!cancellationToken.IsCancellationRequested)
{
int errorRetry = 5;
TaskCompletionSource<bool> tsc = new TaskCompletionSource<bool>();
bool podStopped = false;
using (var podWatcher = (await _kubernetesClient.WatchV1PodAsync(
namespaceName,
podName,
timeoutSeconds: 60,
cancellationToken: cancellationToken)).Watch<V1Pod, V1PodList>((type, item) => { }))
{
podWatcher.OnClosed += () =>
{
tsc.TrySetResult(false);
};
podWatcher.OnError += (ex) =>
{
errorRetry--;
_log.Warning($"Watching '{namespaceName}/{podName}' failed, error {(ex != null ? ex.Message : "null")}.");
if (errorRetry <= 0)
{
podStopped = true;
}
tsc.TrySetResult(false);
};
podWatcher.OnEvent += (watchEventType, d) =>
{
if (watchEventType == WatchEventType.Deleted)
{
_log.Info($"Pod '{namespaceName}/{podName}' is deleted.");
podStopped = true;
tsc.TrySetResult(true);
}
else if (watchEventType == WatchEventType.Modified)
{
_log.Warning($"Pod '{namespaceName}/{podName}' was modified.");
var pod = this._kubernetesClient.GetV1PodAsync(namespaceName, podName, cancellationToken).Result;
if (pod == null || this._IsPodTerminated(pod))
{
_log.Info($"Pod '{namespaceName}/{podName}' terminated.");
podStopped = true;
tsc.TrySetResult(true);
}
}
};
await tsc.Task;
if (podStopped)
{
while (podStopped)
{
// Wait some stabalization period to ensure no more changes
podStopped = false;
await Task.Delay(2000, cancellationToken);
}
return true;
}
}
}
return false;
}