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");
            }
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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);
                    }
                }
            }
        }
Beispiel #6
0
        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);
                }
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
 protected abstract int OnCacheMissLocked(ICompiler comp, DataHash hc, IEnumerable <string> args, CClashRequest req);
Beispiel #9
0
 protected override int OnCacheMissLocked(ICompiler comp, DataHash hc, IEnumerable <string> args, CClashRequest req)
 {
     throw new NotImplementedException();
 }
Beispiel #10
0
 public override int CompileOrCache(ICompiler comp, IEnumerable <string> args, CClashRequest req)
 {
     return(base.CompileOrCache(comp, args, req));
 }