public static async Task RemoveDockerServicesAsync(bool gracefulShutdown = false) { using (var conf = new DockerClientConfiguration(LocalDockerUri())) // localhost using (var client = conf.CreateClient()) { await DockerContainerResults.ForEachAsync(4, async containerResults => { if (gracefulShutdown) { await client.Containers.StopContainerAsync(containerResults.ContainerListResponse.ID, new ContainerStopParameters()); } await client.Containers.RemoveContainerAsync(containerResults.ContainerListResponse.ID, new ContainerRemoveParameters { Force = true }); }); } DockerContainerResults = new ConcurrentBag <DockerContainerResult>(); }
async Task LeaseRenewer() { while (this.isStarted == 1 || !this.shutdownComplete) { try { TraceLog.Informational(string.Format("Host '{0}' starting renewal of Leases.", this.workerName)); ConcurrentBag <T> renewedLeases = new ConcurrentBag <T>(); ConcurrentBag <T> failedToRenewLeases = new ConcurrentBag <T>(); List <Task> renewTasks = new List <Task>(); // Renew leases for all currently owned partitions in parallel foreach (T lease in this.currentlyOwnedPartitions.Values) { renewTasks.Add(this.RenewLeaseAsync(lease).ContinueWith(renewResult => { if (renewResult.Result != null) { renewedLeases.Add(renewResult.Result); } else { // Keep track of all failed attempts to renew so we can trigger shutdown for these partitions failedToRenewLeases.Add(lease); } })); } // Renew leases for all partitions currently in shutdown List <T> failedToRenewShutdownLeases = new List <T>(); foreach (T shutdownLeases in this.keepRenewingDuringClose.Values) { renewTasks.Add(this.RenewLeaseAsync(shutdownLeases).ContinueWith(renewResult => { if (renewResult.Result != null) { renewedLeases.Add(renewResult.Result); } else { // Keep track of all failed attempts to renew shutdown leases so we can remove them from further renew attempts failedToRenewShutdownLeases.Add(shutdownLeases); } })); } // Wait for all renews to complete await Task.WhenAll(renewTasks.ToArray()); // Update renewed leases. foreach (T lease in renewedLeases) { bool updateResult = this.currentlyOwnedPartitions.TryUpdate(lease.PartitionId, lease, lease); if (!updateResult) { TraceLog.Warning(string.Format("Host '{0}' Renewed lease {1} but failed to update it in the map (ignorable).", this.workerName, lease)); } } // Trigger shutdown of all partitions we failed to renew leases await failedToRenewLeases.ForEachAsync( async lease => await this.RemoveLeaseAsync(lease, false, ChangeFeedObserverCloseReason.LeaseLost), this.options.DegreeOfParallelism); // Now remove all failed renewals of shutdown leases from further renewals foreach (T failedToRenewShutdownLease in failedToRenewShutdownLeases) { T removedLease = null; this.keepRenewingDuringClose.TryRemove(failedToRenewShutdownLease.PartitionId, out removedLease); } await Task.Delay(this.options.LeaseRenewInterval, this.leaseRenewerCancellationTokenSource.Token); } catch (OperationCanceledException) { TraceLog.Informational(string.Format("Host '{0}' Renewer task canceled.", this.workerName)); } catch (Exception ex) { TraceLog.Exception(ex); } } this.currentlyOwnedPartitions.Clear(); this.keepRenewingDuringClose.Clear(); TraceLog.Informational(string.Format("Host '{0}' Renewer task completed.", this.workerName)); }