static void Main(string[] args) { Console.CancelKeyPress += Console_CancelKeyPress; if (args.Length < 1) { Console.WriteLine("Usage: RunParServer.exe file.xml"); return; } var force = true; var boogie = false; var debug = false; var test = false; if (args.Any(s => s == "/break")) { System.Diagnostics.Debugger.Launch(); } if (args.Any(s => s == "/debug")) { debug = true; } if (args.Any(s => s == "/noforce")) { force = false; } if (args.Any(s => s == "/resume")) { force = false; resume = true; } if (args.Any(s => s == "/test")) { test = true; } if (args.Any(s => s == "/boogie")) { boogie = true; } // Read in the config config = RunParConfig.DeSerialize(args[0]); config.Dump(); log = new StreamWriter("server.log"); // Check install Console.WriteLine("Checking self installation"); try { Installer.CheckSelfInstall(config); } catch (Exception e) { Console.WriteLine("{0}", e.Message); return; } Console.WriteLine("Done"); // Find the files and their arguments var bpls = new List <Tuple <string, string> >(); var filemaps = new List <string>(); Util.ReadFiles(config, out bpls, out filemaps); Console.WriteLine("Found {0} files", bpls.Count); var machineToFiles = new Dictionary <int, List <string> >(); // Split across machines var M = config.RemoteRoots.Length + 1; for (int i = 0; i < M; i++) { machineToFiles.Add(i, new List <string>()); } for (int i = 0; i < bpls.Count; i++) { machineToFiles[i % M].Add(bpls[i].Item1); } // Do remote installation Console.WriteLine("Doing remote installation"); var rm = 1; foreach (var r in config.RemoteRoots) { Console.WriteLine("Installing {0} files on {1}", machineToFiles[rm].Count, r.value); if (machineToFiles[rm].Count != 0) { Installer.RemoteInstall(config.root, r.value, config.Utils.Select(u => u.dir).Distinct(), machineToFiles[rm], filemaps, boogie, force); } rm++; } Console.WriteLine("Done"); if (debug) { Util.debugOutput = true; } var threads = new List <Thread>(); var workers = new List <Worker>(); var starttime = DateTime.Now; Console.WriteLine("Spawning clients"); // spawn client on own machine config.DumpClientConfig(config.root, machineToFiles[0].Select(f => Util.GetFileName(f, config.root)), System.IO.Path.Combine(config.root, "config-client.xml")); var w0 = new Worker(false, config.root, resume ? "/resume" : "", test ? "/test" : ""); workers.Add(w0); threads.Add(new Thread(new ThreadStart(w0.Run))); // spawn clients on remote machines rm = 0; foreach (var r in config.RemoteRoots) { rm++; if (machineToFiles[rm].Count == 0) { continue; } config.DumpClientConfig(Util.GetRemoteFolder(r.value), machineToFiles[rm].Select(f => Util.GetFileName(f, config.root)), System.IO.Path.Combine(r.value, "config-client.xml")); var w1 = new Worker(true, r.value, resume ? "/resume" : "", test ? "/test" : ""); threads.Add(new Thread(new ThreadStart(w1.Run))); workers.Add(w1); } // start threads threads.ForEach(t => t.Start()); threads.ForEach(t => t.Join()); Console.WriteLine("Time taken = {0} seconds", (DateTime.Now - starttime).TotalSeconds.ToString("F2")); Console.WriteLine("Collating results"); // put the results together foreach (var u in config.Utils) { MergeResults(u, workers, u.name + ".db"); } // text result var output = new System.IO.StreamWriter(System.IO.Path.Combine(config.root, "results.txt")); // file -> util -> output var resdict = new Dictionary <string, Dictionary <string, string> >(); var defaultDelim = 0; foreach (var w in workers) { foreach (var line in w.textresult) { var tokens = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length < 2) { continue; } if (!resdict.ContainsKey(tokens[1])) { resdict.Add(tokens[1], new Dictionary <string, string>()); } var result = ""; for (int i = 2; i < tokens.Length; i++) { result += tokens[i] + "\t"; } defaultDelim = (tokens.Length - 2); // Ideally, this should be the most frequest distribution of this number resdict[tokens[1]][tokens[0]] = result; } } var defaultStr = ""; for (int i = 0; i < defaultDelim; i++) { defaultStr += "XXX\t"; } foreach (var file in bpls) { var key = Util.GetFileName(file.Item1, config.root); if (!resdict.ContainsKey(key)) { continue; } output.Write("{0}\t", key); foreach (var u in config.Utils) { if (!resdict[key].ContainsKey(u.name)) { output.Write("{0}", defaultStr); } else { output.Write("{0}", resdict[key][u.name]); } } output.WriteLine(); } output.Close(); log.Close(); Console.WriteLine("Done"); }