public static Task WaitForStatusAsync(EdgeModule[] modules, EdgeModuleStatus desired, CancellationToken token) { (string template, string[] args) FormatModulesList() => modules.Length == 1 ? ("module '{0}'", new[] { modules.First().Id }) : ("modules ({0})", modules.Select(module => module.Id).ToArray()); string SentenceCase(string input) => $"{input.First().ToString().ToUpper()}{input.Substring(1)}"; async Task WaitForStatusAsync() { await Retry.Do( async() => { string[] output = await Process.RunAsync("iotedge", "list", token); Log.Verbose(string.Join("\n", output)); return(output .Where( ln => { var columns = ln.Split(null as char[], StringSplitOptions.RemoveEmptyEntries); foreach (var module in modules) { // each line is "name status" if (columns[0] == module.Id && columns[1].Equals(desired.ToString(), StringComparison.OrdinalIgnoreCase)) { return true; } } return false; }).ToArray()); }, a => a.Length == modules.Length, e => { // Retry if iotedged's management endpoint is still starting up, // and therefore isn't responding to `iotedge list` yet bool DaemonNotReady(string details) => details.Contains("Could not list modules", StringComparison.OrdinalIgnoreCase) || details.Contains("Socket file could not be found", StringComparison.OrdinalIgnoreCase); return(DaemonNotReady(e.ToString())); }, TimeSpan.FromSeconds(5), token); } (string template, string[] args) = FormatModulesList(); return(Profiler.Run( WaitForStatusAsync, string.Format(SentenceCase(template), "{Modules}") + " entered the '{Desired}' state", string.Join(", ", args), desired.ToString().ToLower())); }
public static Task WaitForStatusAsync(IEnumerable <EdgeModule> modules, EdgeModuleStatus desired, CancellationToken token) { string[] moduleIds = modules.Select(m => m.Id.TrimStart('$')).Distinct().ToArray(); string FormatModulesList() => moduleIds.Length == 1 ? "Module '{0}'" : "Modules ({0})"; async Task WaitForStatusAsync() { await Retry.Do( async() => { string[] output = await Process.RunAsync("iotedge", "list", token); Log.Verbose(string.Join("\n", output)); return(output .Where( ln => { string[] columns = ln.Split(null as char[], StringSplitOptions.RemoveEmptyEntries); foreach (string moduleId in moduleIds) { // each line is "name status" if (columns[0] == moduleId && columns[1].Equals(desired.ToString(), StringComparison.OrdinalIgnoreCase)) { return true; } } return false; }).ToArray()); }, a => a.Length == moduleIds.Length, e => { // Retry if iotedged's management endpoint is still starting up, // and therefore isn't responding to `iotedge list` yet bool DaemonNotReady(string details) => details.Contains("Could not list modules", StringComparison.OrdinalIgnoreCase) || details.Contains("Socket file could not be found", StringComparison.OrdinalIgnoreCase); return(DaemonNotReady(e.ToString())); }, TimeSpan.FromSeconds(5), token); } return(Profiler.Run( WaitForStatusAsync, string.Format(FormatModulesList(), "{Modules}") + " entered the '{Desired}' state", string.Join(", ", moduleIds), desired.ToString().ToLower())); }
public static Task WaitForStatusAsync(EdgeModule[] modules, EdgeModuleStatus desired, CancellationToken token) { string FormatModulesList() => modules.Length == 1 ? $"module '{modules.First().Id}'" : $"modules ({string.Join(", ", modules.Select(module => module.Id))})"; async Task WaitForStatusAsync() { try { await Retry.Do( async() => { string[] result = await Process.RunAsync("iotedge", "list", token); return(result .Where( ln => { var columns = ln.Split(null as char[], StringSplitOptions.RemoveEmptyEntries); foreach (var module in modules) { // each line is "name status" if (columns[0] == module.Id && columns[1].Equals(desired.ToString(), StringComparison.OrdinalIgnoreCase)) { return true; } } return false; }).ToArray()); }, a => a.Length == modules.Length, e => { // Retry if iotedged's management endpoint is still starting up, // and therefore isn't responding to `iotedge list` yet bool DaemonNotReady(string details) => details.Contains("Could not list modules", StringComparison.OrdinalIgnoreCase) || details.Contains("Socket file could not be found", StringComparison.OrdinalIgnoreCase); return(DaemonNotReady(e.ToString())); }, TimeSpan.FromSeconds(5), token); } catch (OperationCanceledException) { throw new Exception($"Error: timed out waiting for {FormatModulesList()} to start"); } catch (Exception e) { throw new Exception($"Error searching for {FormatModulesList()}: {e}"); } } return(Profiler.Run( $"Waiting for {FormatModulesList()} to enter the '{desired.ToString().ToLower()}' state", WaitForStatusAsync)); }