public static async System.Threading.Tasks.Task WaitForServiceToStart(this ECSHelper ecs, string cluster, string serviceName, int timeout, int delay = 2500) { var services = await((cluster.IsNullOrEmpty()) ? ecs.ListServicesAsync() : ecs.ListServicesAsync(cluster)); services = services.Where(x => ((serviceName.StartsWith("arn:")) ? x.ARN == serviceName : x.ARN.EndsWith($":service/{serviceName}"))); if (services?.Count() != 1) { throw new Exception($"Could not find service '{serviceName}' for cluster: '{cluster}' or found more then one matching result (In such case use ARN insted of serviceName, or specify cluster) [{services?.Count()}]."); } var service = services.First(); var tt = new TickTimeout(timeout, TickTime.Unit.s, Enabled: true); while (!tt.IsTriggered) { var serviceDescription = await ecs.DescribeServicesAsync(service.Cluster, new string[] { service.ARN }); if (serviceDescription.IsNullOrEmpty()) { throw new Exception($"Could not find or describe service: '{service.ARN}' for the cluster '{service.Cluster}'."); } var result = serviceDescription.First(); if (result.DesiredCount == result.RunningCount) { return; //desired count reached } await System.Threading.Tasks.Task.Delay(delay); } throw new Exception($"Timeout '{timeout}' [s], service: '{service.ARN}' could not reach its desired count in time."); }
public static async Task <ServiceInfo> GetServiceOrDefault(this ECSHelper ecs, string cluster, string serviceName) { var services = await((cluster.IsNullOrEmpty()) ? ecs.ListServicesAsync() : ecs.ListServicesAsync(cluster)); return(services.SingleOrDefault( x => ((serviceName.StartsWith("arn:")) ? x.ARN == serviceName : x.ARN.EndsWith($":service/{serviceName}")))); }
public static async Task <IEnumerable <ServiceInfo> > ListServicesAsync(this ECSHelper ecs, string cluster, bool throwIfNotFound = true) { IEnumerable <string> fargateServices = null; IEnumerable <string> ec2Services = null; try { fargateServices = await ecs.ListServicesAsync(cluster, LaunchType.FARGATE); ec2Services = await ecs.ListServicesAsync(cluster, LaunchType.EC2); } catch (ClusterNotFoundException) { if (throwIfNotFound) { throw; } return(null); } return(fargateServices.Select(x => new ServiceInfo(cluster: cluster, arn: x, launchType: LaunchType.FARGATE)) .ConcatOrDefault(ec2Services.Select(x => new ServiceInfo(cluster: cluster, arn: x, launchType: LaunchType.EC2)))); }
public static async System.Threading.Tasks.Task DestroyService(this ECSHelper ecs, string cluster, string serviceName, bool throwIfNotFound = true, int drainingTimeout = 5 *60 *1000) { var services = await((cluster.IsNullOrEmpty()) ? ecs.ListServicesAsync() : ecs.ListServicesAsync(cluster, throwIfNotFound: throwIfNotFound)); services = services?.Where(x => ((serviceName.StartsWith("arn:")) ? x.ARN == serviceName : x.ARN.EndsWith($":service/{serviceName}"))); if (!throwIfNotFound && (services?.Count() ?? 0) == 0) { return; } if (services?.Count() != 1) { throw new Exception($"Could not find service '{serviceName}' for cluster: '{cluster}' or found more then one matching result (In such case use ARN insted of serviceName, or specify cluster) [{services?.Count()}]."); } var service = services.First(); var tasks = await ecs.ListTasksAsync(service.Cluster, service.ARN); if ((tasks?.Count() ?? 0) != 0) { await ecs.StopTasksAsync(arns : tasks, cluster : service.Cluster); } await ecs.UpdateServiceAsync(desiredCount : 0, arns : service.ARN, cluster : service.Cluster); await ecs.DeleteServiceAsync(cluster : service.Cluster, arns : service.ARN); //ensure service is in draining state await System.Threading.Tasks.Task.Delay(1000); string status = null; var sw = Stopwatch.StartNew(); //ensure service is not in draining state before finishing while ((status = ((await ecs.DescribeServicesAsync(cluster: cluster, services: new string[] { serviceName })).FirstOrDefault())?.Status) == "DRAINING") { if (sw.ElapsedMilliseconds > drainingTimeout) { throw new Exception($"Could not drain the service '{serviceName}' for cluster: '{cluster}', elapsed {sw.ElapsedMilliseconds}/{drainingTimeout} [ms]."); } await System.Threading.Tasks.Task.Delay(1000); } }