Example #1
0
        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.");
        }
Example #2
0
        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);
            }
        }