public CClashResponse Transact(CClashRequest req) { Connect(); CClashResponse resp = null; req.pid = System.Diagnostics.Process.GetCurrentProcess().Id; var txbuf = req.Serialize(); ncs.Write(txbuf, 0, txbuf.Length); ncs.Flush(); var rx = new List <byte>(); var rxbuf = new byte[8192]; do { var rbytes = ncs.Read(rxbuf, 0, rxbuf.Length); rx.AddRange(rxbuf.Take(rbytes)); } while (!ncs.IsMessageComplete); if (rx.Count > 0) { resp = CClashMessage.Deserialize <CClashResponse>(rx.ToArray()); ncs.Close(); } return(resp); }
public string GetStats(string compiler) { var req = new CClashRequest() { cmd = Command.GetStats, compiler = compiler, }; var resp = Transact(req); return(resp.stdout); }
public int CompileOrCache(ICompiler comp, IEnumerable <string> args) { Logging.Emit("client args: {0}", string.Join(" ", args.ToArray())); if (comp != null) // compiler is set, server wasnt ready { return(comp.InvokeCompiler(args, null, null, false, new List <string>())); } try { var req = new CClashRequest() { cmd = Command.Run, compiler = compilerPath, envs = environment, workdir = workingdir, argv = new List <string> (args), }; var resp = Transact(req); if (resp != null) { if (stdErrCallback != null) { stdErrCallback(resp.stderr); } else { Console.Error.Write(resp.stderr); } if (stdOutCallback != null) { stdOutCallback(resp.stdout); } else { Console.Out.Write(resp.stdout); } return(resp.exitcode); } else { throw new CClashErrorException("server returned no response"); } } catch (Exception e) { Logging.Emit("server error! {0}", e); throw new CClashWarningException("server error"); } }
public virtual int CompileOrCache(ICompiler comp, IEnumerable <string> args, CClashRequest req) { if (IsSupported(comp, args)) { args = comp.CompileArgs; var hc = DeriveHashKey(comp, args); if (hc.Result == DataHashResult.Ok) { CacheManifest hm; if (CheckCache(comp, args, hc, out hm)) { Logging.Hit(hc.Hash, comp.WorkingDirectory, comp.ObjectTarget); return(OnCacheHitLocked(comp, hc, hm)); } else { // miss, try build return(OnCacheMissLocked(comp, hc, args, req)); } } } else { if (comp.SingleSource || comp.SourceFiles.Count() == 0) { Stats.LockStatsCall(() => Stats.CacheUnsupported++); } else { return(RunMultipleCompilers(comp, args)); } } if (comp.ResponseFile != null) { if (File.Exists(comp.ResponseFile)) { //var resp = File.ReadAllText(comp.ResponseFile); } } return(CompileOnly(comp, args)); }
protected virtual void DoCacheMiss(ICompiler c, DataHash hc, IEnumerable <string> args, CClashRequest req, List <string> ifiles) { bool good = true; CacheManifest m = null; try { var idirs = c.GetUsedIncludeDirs(ifiles); if (idirs.Count < 1) { throw new InvalidDataException( string.Format("could not find any include folders?! [{0}]", string.Join(" ", args))); } #region process includes folders // save manifest and other things to cache var others = c.GetPotentialIncludeFiles(idirs, ifiles); m = new CacheManifest(); m.Request = req; m.PotentialNewIncludes = others; m.IncludeFiles = new Dictionary <string, string>(); m.TimeStamp = DateTime.Now.ToString("s"); m.SessionHash = hc.SessionHash; #endregion var hashes = GetHashes(ifiles, c.WorkingDirectory); #region check include files foreach (var x in hashes) { if (x.Value.Result == DataHashResult.Ok) { m.IncludeFiles[x.Key] = x.Value.Hash; } else { Logging.Emit("input hash error {0} {1}", x.Key, x.Value.Result); Logging.Miss(hc.SessionHash, x.Value.Result, c.WorkingDirectory, c.SingleSourceFile, x.Key); good = false; m.Disable = true; break; } } #endregion } finally { Unlock(CacheLockType.Read); if (good) { Lock(CacheLockType.ReadWrite); try { if (m != null) { SaveOutputsLocked(m, c); } } finally { Unlock(CacheLockType.ReadWrite); } } } }
protected override int OnCacheMissLocked(ICompiler comp, DataHash hc, IEnumerable <string> args, CClashRequest req) { Logging.Emit("cache miss"); outputCache.EnsureKey(hc.Hash); var ifiles = new List <string>(); Stats.LockStatsCall(() => Stats.CacheMisses++); using (var stderr = outputCache.OpenFileStream(hc.Hash, F_Stderr, FileMode.OpenOrCreate, FileAccess.Write)) using (var stdout = outputCache.OpenFileStream(hc.Hash, F_Stdout, FileMode.OpenOrCreate, FileAccess.Write)) { int rv = Compile(comp, args, stderr, stdout, ifiles); // we still hold the cache lock, create the manifest asap or give up now! if (rv != 0) { Unlock(CacheLockType.Read); } else { // this unlocks for us try { DoCacheMiss(comp, hc, args, req, ifiles); } catch (CClashWarningException) { return(CompileOnly(comp, args)); } } return(rv); } }
public CClashResponse ProcessRequest(CClashRequest req) { var rv = new CClashResponse() { supported = false }; Logging.Emit("{0}", DateTime.Now.ToString("s")); Logging.Emit("server req: cmd = {0}, workdir = {1}", req.cmd, req.workdir); switch (req.cmd) { case Command.GetStats: rv.exitcode = 0; cache.SetupStats(); // commits stats to disk rv.stdout = StatOutputs.GetStatsString(req.compiler, cache); break; case Command.DisableCache: DisableCaching = true; rv.supported = true; break; case Command.ClearCache: DisableCaching = true; cache.SetupStats(); cache.Lock(CacheLockType.ReadWrite); cache.OutputCache.ClearLocked(); cache.IncludeCache.ClearLocked(); cache.Unlock(CacheLockType.ReadWrite); rv.supported = true; break; case Command.EnableCache: DisableCaching = false; rv.supported = true; break; case Command.Run: var stdout = new StringBuilder(); var stderr = new StringBuilder(); var comp = cache.SetCompilerEx(req.pid, req.compiler, req.workdir, new Dictionary <string, string>(req.envs)); cache.SetCaptureCallback(comp, (so) => { stdout.Append(so); }, (se) => { stderr.Append(se); }); if (DisableCaching) { rv.exitcode = comp.InvokeCompiler(req.argv, null, null, false, new List <string>()); } else { rv.exitcode = cache.CompileOrCache(comp, req.argv); } rv.supported = true; rv.stderr = stderr.ToString(); rv.stdout = stdout.ToString(); break; case Command.Quit: cache.SetupStats(); Stop(); break; } Logging.Emit("server resp: {0}", rv.exitcode); return(rv); }
protected abstract int OnCacheMissLocked(ICompiler comp, DataHash hc, IEnumerable <string> args, CClashRequest req);
protected override int OnCacheMissLocked(ICompiler comp, DataHash hc, IEnumerable <string> args, CClashRequest req) { throw new NotImplementedException(); }
public override int CompileOrCache(ICompiler comp, IEnumerable <string> args, CClashRequest req) { return(base.CompileOrCache(comp, args, req)); }