internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart)
 {
     if (!(result is BuildResultCompiledTemplateType))
     {
         base.CacheBuildResult(cacheKey, result, hashCode, utcStart);
     }
 }
 internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart)
 {
     if (!BuildResultCompiledType.UsesDelayLoadType(result))
     {
         ICollection virtualPathDependencies = result.VirtualPathDependencies;
         CacheDependency dependencies = null;
         if (virtualPathDependencies != null)
         {
             dependencies = result.VirtualPath.GetCacheDependency(virtualPathDependencies, utcStart);
             if (dependencies != null)
             {
                 result.UsesCacheDependency = true;
             }
         }
         if (result.CacheToMemory)
         {
             CacheItemPriority normal;
             BuildResultCompiledAssemblyBase base2 = result as BuildResultCompiledAssemblyBase;
             if (((base2 != null) && (base2.ResultAssembly != null)) && !base2.UsesExistingAssembly)
             {
                 string assemblyCacheKey = BuildResultCache.GetAssemblyCacheKey(base2.ResultAssembly);
                 Assembly assembly = (Assembly) this._cache.Get(assemblyCacheKey);
                 if (assembly == null)
                 {
                     this._cache.UtcInsert(assemblyCacheKey, base2.ResultAssembly, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
                 }
                 CacheDependency dependency2 = new CacheDependency(0, null, new string[] { assemblyCacheKey });
                 if (dependencies != null)
                 {
                     AggregateCacheDependency dependency3 = new AggregateCacheDependency();
                     dependency3.Add(new CacheDependency[] { dependencies, dependency2 });
                     dependencies = dependency3;
                 }
                 else
                 {
                     dependencies = dependency2;
                 }
             }
             string memoryCacheKey = GetMemoryCacheKey(cacheKey);
             if (result.IsUnloadable)
             {
                 normal = CacheItemPriority.Normal;
             }
             else
             {
                 normal = CacheItemPriority.NotRemovable;
             }
             CacheItemRemovedCallback onRemoveCallback = null;
             if (result.ShutdownAppDomainOnChange || (result is BuildResultCompiledAssemblyBase))
             {
                 if (this._onRemoveCallback == null)
                 {
                     this._onRemoveCallback = new CacheItemRemovedCallback(this.OnCacheItemRemoved);
                 }
                 onRemoveCallback = this._onRemoveCallback;
             }
             this._cache.UtcInsert(memoryCacheKey, result, dependencies, result.MemoryCacheExpiration, result.MemoryCacheSlidingExpiration, normal, onRemoveCallback);
         }
     }
 }
 internal void SaveBuildResultToFile(string preservationFile, BuildResult result, long hashCode)
 {
     this._writer = new XmlTextWriter(preservationFile, Encoding.UTF8);
     try
     {
         this._writer.Formatting = Formatting.Indented;
         this._writer.Indentation = 4;
         this._writer.WriteStartDocument();
         this._writer.WriteStartElement("preserve");
         this.SetAttribute("resultType", ((int) result.GetCode()).ToString(CultureInfo.InvariantCulture));
         if (result.VirtualPath != null)
         {
             this.SetAttribute("virtualPath", result.VirtualPath.VirtualPathString);
         }
         this.SetAttribute("hash", result.ComputeHashCode(hashCode).ToString("x", CultureInfo.InvariantCulture));
         string virtualPathDependenciesHash = result.VirtualPathDependenciesHash;
         if (virtualPathDependenciesHash != null)
         {
             this.SetAttribute("filehash", virtualPathDependenciesHash);
         }
         result.SetPreservedAttributes(this);
         this.SaveDependencies(result.VirtualPathDependencies);
         this._writer.WriteEndElement();
         this._writer.WriteEndDocument();
         this._writer.Close();
     }
     catch
     {
         this._writer.Close();
         File.Delete(preservationFile);
         throw;
     }
 }
    internal void SaveBuildResultToFile(string preservationFile,
        BuildResult result, long hashCode) {

        _writer = new XmlTextWriter(preservationFile, Encoding.UTF8);

        try {
            _writer.Formatting = Formatting.Indented;
            _writer.Indentation = 4;
            _writer.WriteStartDocument();

            // <preserve assem="assemblyFile">
            _writer.WriteStartElement("preserve");

            // Save the type of BuildResult we're dealing with
            Debug.Assert(result.GetCode() != BuildResultTypeCode.Invalid); 
            SetAttribute("resultType", ((int)result.GetCode()).ToString(CultureInfo.InvariantCulture));

            // Save the virtual path for this BuildResult
            if (result.VirtualPath != null)
                SetAttribute("virtualPath", result.VirtualPath.VirtualPathString);

            // Get the hash code of the BuildResult
            long hash = result.ComputeHashCode(hashCode);

            // The hash should always be valid if we got here.
            Debug.Assert(hash != 0, "hash != 0"); 

            // Save it to the preservation file
            SetAttribute("hash", hash.ToString("x", CultureInfo.InvariantCulture));

            // Can be null if that's what the VirtualPathProvider returns
            string fileHash = result.VirtualPathDependenciesHash;
            if (fileHash != null)
                SetAttribute("filehash", fileHash);

            result.SetPreservedAttributes(this);

            SaveDependencies(result.VirtualPathDependencies);

            // </preserve>
            _writer.WriteEndElement();
            _writer.WriteEndDocument();

            _writer.Close();
        }
        catch {

            // If an exception occurs during the writing of the xml file, clean it up
            _writer.Close();
            File.Delete(preservationFile);

            throw;
        }
    }
 internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart)
 {
     if (result.CacheToDisk)
     {
         if (HostingEnvironment.ShutdownInitiated)
         {
             BuildResultCompiledAssemblyBase base2 = result as BuildResultCompiledAssemblyBase;
             if (base2 != null)
             {
                 this.MarkAssemblyAndRelatedFilesForDeletion(base2.ResultAssembly.GetName().Name);
             }
         }
         else
         {
             string preservedDataFileName = this.GetPreservedDataFileName(cacheKey);
             new PreservationFileWriter(this.PrecompilationMode).SaveBuildResultToFile(preservedDataFileName, result, hashCode);
         }
     }
 }
 internal BuildDependencySet(BuildResult result) {
     _result = result;
 }
예제 #7
0
 internal override void CacheBuildResult(string cacheKey, BuildResult result,
                                         long hashCode, DateTime utcStart)
 {
     // Nothing to cache to disk if the app is already precompiled
 }
예제 #8
0
 static internal bool UsesDelayLoadType(BuildResult result) {
     BuildResultCompiledType buildResultCompiledType = result as BuildResultCompiledType;
     if (buildResultCompiledType != null) {
         return buildResultCompiledType.IsDelayLoadType;
     }
     else {
         return false;
     }
 }
예제 #9
0
        internal override void CacheBuildResult(string cacheKey, BuildResult result,
                                                long hashCode, DateTime utcStart)
        {
            ICollection virtualDependencies = result.VirtualPathDependencies;

            Debug.Trace("BuildResultCache", "Adding cache " + cacheKey + " in the memory cache");

            CacheDependency cacheDependency = null;

            if (virtualDependencies != null)
            {
                cacheDependency = result.VirtualPath.GetCacheDependency(virtualDependencies, utcStart);

                // If we got a cache dependency, remember that in the BuildResult
                if (cacheDependency != null)
                {
                    result.UsesCacheDependency = true;
                }
            }

            // If it should not be cached to memory, leave it alone
            if (!result.CacheToMemory)
            {
                return;
            }

            if (BuildResultCompiledType.UsesDelayLoadType(result))
            {
                // If the result is delaying loading of assembly, then don't cache
                // to avoid having to load the assembly.
                return;
            }

            BuildResultCompiledAssemblyBase compiledResult = result as BuildResultCompiledAssemblyBase;

            if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly)
            {
                // Insert a new cache entry using the assembly path as the key
                string   assemblyKey = GetAssemblyCacheKey(compiledResult.ResultAssembly);
                Assembly a           = (Assembly)HttpRuntime.Cache.InternalCache.Get(assemblyKey);
                if (a == null)
                {
                    Debug.Trace("BuildResultCache", "Adding marker cache entry " + compiledResult.ResultAssembly);
                    // VSWhidbey 500049 - add as NotRemovable to prevent the assembly from being prematurely deleted
                    HttpRuntime.Cache.InternalCache.Insert(assemblyKey, compiledResult.ResultAssembly, null);
                }
                else
                {
                    Debug.Assert(a == compiledResult.ResultAssembly);
                }

                // Now create a dependency based on that key. This way, by removing that key, we are able to
                // remove all the pages that live in that assembly from the cache.
                CacheDependency assemblyCacheDependency = new CacheDependency(0, null, new string[] { assemblyKey });

                if (cacheDependency != null)
                {
                    // We can't share the same CacheDependency, since we don't want the UtcStart
                    // behavior for the assembly.  Use an Aggregate to put the two together.
                    AggregateCacheDependency tmpDependency = new AggregateCacheDependency();
                    tmpDependency.Add(new CacheDependency[] { cacheDependency, assemblyCacheDependency });
                    cacheDependency = tmpDependency;
                }
                else
                {
                    cacheDependency = assemblyCacheDependency;
                }
            }

            string key = GetMemoryCacheKey(cacheKey);

            // Only allow the cache item to expire if the result can be unloaded.  Otherwise,
            // we may as well cache it forever (e.g. for Assemblies and Types).
            CacheItemPriority cachePriority;

            if (result.IsUnloadable)
            {
                cachePriority = CacheItemPriority.Default;
            }
            else
            {
                cachePriority = CacheItemPriority.NotRemovable;
            }

            CacheItemRemovedCallback onRemoveCallback = null;

            // If the appdomain needs to be shut down when the item becomes invalid, register
            // a callback to do the shutdown.
            if (result.ShutdownAppDomainOnChange || result is BuildResultCompiledAssemblyBase)
            {
                // Create the delegate on demand
                if (_onRemoveCallback == null)
                {
                    _onRemoveCallback = new CacheItemRemovedCallback(OnCacheItemRemoved);
                }

                onRemoveCallback = _onRemoveCallback;
            }

            HttpRuntime.Cache.InternalCache.Insert(key, result, new CacheInsertOptions()
            {
                Dependencies       = cacheDependency,
                AbsoluteExpiration = result.MemoryCacheExpiration,
                SlidingExpiration  = result.MemoryCacheSlidingExpiration,
                Priority           = cachePriority,
                OnRemovedCallback  = onRemoveCallback
            });
        }
예제 #10
0
 internal abstract void CacheBuildResult(string cacheKey, BuildResult result,
                                         long hashCode, DateTime utcStart);
 internal void CacheBuildResult(string cacheKey, BuildResult result, DateTime utcStart) {
     CacheBuildResult(cacheKey, result, 0 /*hashCode*/, utcStart);
 }
 internal abstract void CacheBuildResult(string cacheKey, BuildResult result,
     long hashCode, DateTime utcStart);
 internal void SetBuildResultDependencies(BuildResult result)
 {
     result.AddVirtualPathDependencies(this.VirtualPathDependencies);
 }
 internal static bool UsesDelayLoadType(BuildResult result)
 {
     BuildResultCompiledType type = result as BuildResultCompiledType;
     return ((type != null) && type.IsDelayLoadType);
 }
예제 #15
0
 internal BuildDependencySet(BuildResult result)
 {
     this._result = result;
 }
예제 #16
0
        private BuildResult ReadFileInternal(VirtualPath virtualPath, string preservationFile, long hashCode, bool ensureIsUpToDate)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(preservationFile);

            // Get the root element, and make sure it's what we expect
            _root = doc.DocumentElement;
            Debug.Assert(_root != null && _root.Name == "preserve", "_root != null && _root.Name == \"preserve\"");
            if (_root == null || _root.Name != "preserve")
            {
                return(null);
            }

            // Get the type of the BuildResult preserved in this file
            string resultTypeCodeString        = GetAttribute("resultType");
            BuildResultTypeCode resultTypeCode = (BuildResultTypeCode)Int32.Parse(
                resultTypeCodeString, CultureInfo.InvariantCulture);

            // Get the config path that affects this BuildResult if one wasn't passed in.
            // Note that the passed in path may be different with Sharepoint-like ghosting (VSWhidbey 343230)
            if (virtualPath == null)
            {
                virtualPath = VirtualPath.Create(GetAttribute("virtualPath"));
            }

            long   savedHash     = 0;
            string savedFileHash = null;

            // Ignore dependencies in precompilation mode
            if (!_precompilationMode)
            {
                // Read the saved hash from the preservation file
                string hashString = GetAttribute("hash");
                Debug.Assert(hashString != null, "hashString != null");
                if (hashString == null)
                {
                    return(null);
                }

                // Parse the saved hash string as an hex int
                savedHash = Int64.Parse(hashString, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);

                // Read the saved file hash from the preservation file.  This is the hash the represents
                // the state of all the virtual files that the build result depends on.
                savedFileHash = GetAttribute("filehash");
            }

            // Create the BuildResult accordingly
            BuildResult result = BuildResult.CreateBuildResultFromCode(resultTypeCode, virtualPath);

            // Ignore dependencies in precompilation mode
            if (!_precompilationMode)
            {
                ReadDependencies();
                if (_sourceDependencies != null)
                {
                    result.SetVirtualPathDependencies(_sourceDependencies);
                }

                result.VirtualPathDependenciesHash = savedFileHash;

                // Check if the build result is up to date
                bool outOfDate = false;
                if (!result.IsUpToDate(virtualPath, ensureIsUpToDate))
                {
                    Debug.Trace("PreservationFileReader", Path.GetFileName(preservationFile) +
                                " is out of date (IsUpToDate==false)");

                    outOfDate = true;
                }
                else
                {
                    // The virtual paths hash code was up to date, so check the
                    // other hash code.

                    // Get the current hash code
                    long currentHash = result.ComputeHashCode(hashCode);

                    // If the hash doesn't match, the preserved data is out of date
                    if (currentHash == 0 || currentHash != savedHash)
                    {
                        outOfDate = true;
                        Debug.Trace("PreservationFileReader", Path.GetFileName(preservationFile) +
                                    " is out of date (ComputeHashCode)");
                    }
                }

                if (outOfDate)
                {
                    bool gotLock = false;
                    try {
                        // We need to delete the preservation file together with the assemblies/pdbs
                        // under the same lock so to avoid bad interleaving where one process
                        // deletes the .compiled file that another process just created, orphaning
                        // the files generated by the other process.
                        // (Dev10
                        CompilationLock.GetLock(ref gotLock);

                        // Give the BuildResult a chance to do some cleanup
                        result.RemoveOutOfDateResources(this);

                        // The preservation file is not useable, so delete it
                        File.Delete(preservationFile);
                    }
                    finally {
                        // Always release the mutex if we had taken it
                        if (gotLock)
                        {
                            CompilationLock.ReleaseLock();
                        }
                    }
                    return(null);
                }
            }

            // Ask the BuildResult to read the data it needs
            result.GetPreservedAttributes(this);

            return(result);
        }
예제 #17
0
        private void AddBuildProviders(bool retryIfDeletionHappens)
        {
            DiskBuildResultCache.ResetAssemblyDeleted();

            foreach (VirtualFile vfile in _vdir.Files)
            {
                // If it's already built and up to date, skip it
                BuildResult result = null;
                try {
                    result = BuildManager.GetVPathBuildResultFromCache(vfile.VirtualPathObject);
                }
                catch {
                    // Ignore the cached error in batch compilation mode, since we want to compile
                    // as many files as possible.
                    // But don't ignore it in CBM or precompile cases, since we always want to try
                    // to compile everything that had failed before.
                    if (!BuildManager.PerformingPrecompilation)
                    {
                        // Skip it if an exception occurs (e.g. if a compile error was cached for it)
                        continue;
                    }
                }

                if (result != null)
                {
                    continue;
                }

                BuildProvider buildProvider = BuildManager.CreateBuildProvider(vfile.VirtualPathObject,
                                                                               _compConfig, _referencedAssemblies, false /*failIfUnknown*/);

                // Non-supported file type
                if (buildProvider == null)
                {
                    continue;
                }

                // IgnoreFileBuildProvider's should never be created
                Debug.Assert(!(buildProvider is IgnoreFileBuildProvider));

                _buildProviders[vfile.VirtualPath] = buildProvider;
            }

            // If an assembly had to be deleted/renamed as a result of calling GetVPathBuildResultFromCache,
            // me way need to run the AddBuildProviders logic again.  The reason is that as a result of
            // deleting the assembly, we may have invalidated other BuildResult that we had earlier found
            // to be up to date (VSWhidbey 269297)
            if (DiskBuildResultCache.InUseAssemblyWasDeleted)
            {
                Debug.Assert(retryIfDeletionHappens);

                // Only retry if we're doing precompilation.  For standard batching, we can live
                // with the fact that not everything will be built after we're done (and we want to
                // be done as quickly as possible since the user is waiting).
                if (retryIfDeletionHappens && BuildManager.PerformingPrecompilation)
                {
                    Debug.Trace("WebDirectoryBatchCompiler", "Rerunning AddBuildProviders for '" +
                                _vdir.VirtualPath + "' because an assembly was out of date.");

                    // Pass false for retryIfDeletionHappens to make sure we don't get in an
                    // infinite recursion.
                    AddBuildProviders(false /*retryIfDeletionHappens*/);
                }
            }
        }
        internal static bool UsesDelayLoadType(BuildResult result)
        {
            BuildResultCompiledType type = result as BuildResultCompiledType;

            return((type != null) && type.IsDelayLoadType);
        }
 internal void CacheBuildResult(string cacheKey, BuildResult result, DateTime utcStart)
 {
     this.CacheBuildResult(cacheKey, result, 0L, utcStart);
 }
    internal override void CacheBuildResult(string cacheKey, BuildResult result,
        long hashCode, DateTime utcStart) {

        // Nothing to cache to disk if the app is already precompiled
    }
 internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart)
 {
 }
    internal override void CacheBuildResult(string cacheKey, BuildResult result,
        long hashCode, DateTime utcStart) {

        ICollection virtualDependencies = result.VirtualPathDependencies;

        Debug.Trace("BuildResultCache", "Adding cache " + cacheKey + " in the memory cache");

        CacheDependency cacheDependency = null;

        if (virtualDependencies != null) {
            cacheDependency = result.VirtualPath.GetCacheDependency(virtualDependencies, utcStart);

            // If we got a cache dependency, remember that in the BuildResult
            if (cacheDependency != null)
                result.UsesCacheDependency = true;
        }

        // If it should not be cached to memory, leave it alone
        if (!result.CacheToMemory) {
            return;
        }

        if (BuildResultCompiledType.UsesDelayLoadType(result)) {
            // If the result is delaying loading of assembly, then don't cache
            // to avoid having to load the assembly.
            return;
        }

        BuildResultCompiledAssemblyBase compiledResult = result as BuildResultCompiledAssemblyBase;
        if (compiledResult != null && compiledResult.ResultAssembly != null && !compiledResult.UsesExistingAssembly) {

            // Insert a new cache entry using the assembly path as the key
            string assemblyKey = GetAssemblyCacheKey(compiledResult.ResultAssembly);
            Assembly a = (Assembly)_cache.Get(assemblyKey);
            if (a == null) {
                Debug.Trace("BuildResultCache", "Adding marker cache entry " + compiledResult.ResultAssembly);
                // VSWhidbey 500049 - add as NotRemovable to prevent the assembly from being prematurely deleted
                _cache.UtcInsert(assemblyKey, compiledResult.ResultAssembly,
                                 null,
                                 Cache.NoAbsoluteExpiration,
                                 Cache.NoSlidingExpiration,
                                 CacheItemPriority.NotRemovable,
                                 null);
            }
            else {
                Debug.Assert(a == compiledResult.ResultAssembly);
            }

            // Now create a dependency based on that key. This way, by removing that key, we are able to
            // remove all the pages that live in that assembly from the cache.
            CacheDependency assemblyCacheDependency = new CacheDependency(0, null, new string[] { assemblyKey });

            if (cacheDependency != null) {
                // We can't share the same CacheDependency, since we don't want the UtcStart
                // behavior for the assembly.  Use an Aggregate to put the two together.
                AggregateCacheDependency tmpDependency = new AggregateCacheDependency();
                tmpDependency.Add(new CacheDependency[] { cacheDependency, assemblyCacheDependency });
                cacheDependency = tmpDependency;
            }
            else {
                cacheDependency = assemblyCacheDependency;
            }
        }

        string key = GetMemoryCacheKey(cacheKey);

        // Only allow the cache item to expire if the result can be unloaded.  Otherwise,
        // we may as well cache it forever (e.g. for Assemblies and Types).
        CacheItemPriority cachePriority;
        if (result.IsUnloadable)
            cachePriority = CacheItemPriority.Default;
        else
            cachePriority = CacheItemPriority.NotRemovable;

        CacheItemRemovedCallback onRemoveCallback = null;

        // If the appdomain needs to be shut down when the item becomes invalid, register
        // a callback to do the shutdown.
        if (result.ShutdownAppDomainOnChange || result is BuildResultCompiledAssemblyBase) {

            // Create the delegate on demand
            if (_onRemoveCallback == null)
                _onRemoveCallback = new CacheItemRemovedCallback(OnCacheItemRemoved);

            onRemoveCallback = _onRemoveCallback;
        }

        _cache.UtcInsert(key, result, cacheDependency,
            result.MemoryCacheExpiration,
            result.MemoryCacheSlidingExpiration,
            cachePriority,
            onRemoveCallback);
    }
예제 #23
0
        private BuildResult PostProcessFoundBuildResult(BuildResult result, bool keyFromVPP, VirtualPath virtualPath) {

            // Check that the virtual path in the result matches the passed in
            // virtualPath (VSWhidbey 516641).  But skip this check in case the key came from
            // calling VirtualPathProvider.GetCacheKey, as it may legitimately not match.
            if (!keyFromVPP) {
                if (virtualPath != null && virtualPath != result.VirtualPath) {
                    Debug.Assert(false);
                    return null;
                }
            }

            // If what we found in the cache is a CompileError, rethrow the exception
            if (result is BuildResultCompileError) {
                // Report the cached error from Callback interface.
                HttpCompileException compileException = ((BuildResultCompileError)result).CompileException;

                // But don't report it if we're doing precompilation, as that would cause it to be
                // reported twice because we always try to compile everything that has failed
                // before (VSWhidbey 525414)
                if (!PerformingPrecompilation) {
                    ReportErrorsFromException(compileException);
                }

                throw compileException;
            }

            return result;
        }
    internal override void CacheBuildResult(string cacheKey, BuildResult result,
        long hashCode, DateTime utcStart) {

        // If it should not be cached to disk, leave it alone
        if (!result.CacheToDisk)
            return;

        // VSWhidbey 564168 don't save to disk if already shutting down, otherwise we might
        // be persisting assembly that was compiled with obsolete references.
        // Since we are shutting down and not creating any cache, delete the compiled result 
        // as it will not be used in future.
        if (HostingEnvironment.ShutdownInitiated) {
            BuildResultCompiledAssemblyBase compiledResult = result as BuildResultCompiledAssemblyBase;
            if (compiledResult != null)
                MarkAssemblyAndRelatedFilesForDeletion(compiledResult.ResultAssembly.GetName().Name);
            return;
        }

        string preservationFile = GetPreservedDataFileName(cacheKey);
        PreservationFileWriter pfw = new PreservationFileWriter(PrecompilationMode);

        pfw.SaveBuildResultToFile(preservationFile, result, hashCode);
    }
예제 #25
0
        private bool CacheVPathBuildResultInternal(VirtualPath virtualPath,
            BuildResult result, DateTime utcStart) {

            string cacheKey = GetCacheKeyFromVirtualPath(virtualPath);
            return CacheBuildResult(cacheKey, result, utcStart);
        }
    internal override void CacheBuildResult(string cacheKey, BuildResult result,
        long hashCode, DateTime utcStart) {

        // Don't create preservation files in bin for pages in the updatable model,
        // because we turn them into a v1 style code behind, which works as a result of
        // having the aspx file point to the bin class via an inherits attribute.
        if (result is BuildResultCompiledTemplateType)
            return;

        base.CacheBuildResult(cacheKey, result, hashCode, utcStart);
    }
예제 #27
0
        private bool CacheBuildResultInternal(string cacheKey, BuildResult result,
            long hashCode, DateTime utcStart) {

            // Before caching it, make sure the hash has been computed
            result.EnsureVirtualPathDependenciesHashComputed();

            for (int i = 0; i < _caches.Length; i++) {
                _caches[i].CacheBuildResult(cacheKey, result, hashCode, utcStart);
            }

            // If we find that it's no longer valid after caching it, remove it from the cache (VSWhidbey 578372)
            if (!TimeStampChecker.CheckFilesStillValid(cacheKey, result.VirtualPathDependencies)) {
                _memoryCache.RemoveAssemblyAndCleanupDependencies(result as BuildResultCompiledAssemblyBase);
                return false;
            }

            return true;
        }
        [global::Umbraco.Web.WebApi.UmbracoAuthorize] // can use Umbraco's
        public HttpResponseMessage BuildModels()
        {
            try
            {
                // the UmbracoAuthorize attribute validates the current user
                // the UmbracoAuthorizedApiController would in addition check for .Disabled and .NoConsole
                // but to do it it relies on internal methods so we have to do it here explicitely

                // was doing it using legacy User class, now using new API class

                //var user = umbraco.BusinessLogic.User.GetCurrent();
                var user = UmbracoContext.Security.CurrentUser;
                //if (user.Disabled || user.NoConsole)
                if (!user.IsApproved && user.IsLockedOut)
                    return new HttpResponseMessage(HttpStatusCode.Unauthorized);
                //if (user.Applications.All(x => x.alias != "developer"))
                if (!user.AllowedSections.Contains("developer"))
                    return new HttpResponseMessage(HttpStatusCode.Unauthorized);

                if (!Config.EnableAppDataModels && !Config.EnableAppCodeModels && !Config.EnableDllModels)
                {
                    var result2 = new BuildResult { Success = false, Message = "Models generation is not enabled." };
                    return Request.CreateResponse(HttpStatusCode.OK, result2, Configuration.Formatters.JsonFormatter);
                }

                var appData = HostingEnvironment.MapPath("~/App_Data");
                if (appData == null)
                    throw new Exception("Panic: appData is null.");

                var appCode = HostingEnvironment.MapPath("~/App_Code");
                if (appCode == null)
                    throw new Exception("Panic: appCode is null.");

                var bin = HostingEnvironment.MapPath("~/bin");
                if (bin== null)
                    throw new Exception("Panic: bin is null.");

                // EnableDllModels will recycle the app domain - but this request will end properly
                GenerateModels(appData, Config.EnableDllModels ? bin : null);

                // will recycle the app domain - but this request will end properly
                if (Config.EnableAppCodeModels)
                    TouchModelsFile(appCode);

                var result = new BuildResult {Success = true};
                return Request.CreateResponse(HttpStatusCode.OK, result, Configuration.Formatters.JsonFormatter);

            }
            catch (Exception e)
            {
                var message = string.Format("{0}: {1}\r\n{2}", e.GetType().FullName, e.Message, e.StackTrace);
                var result = new BuildResult { Success = false, Message = message };
                return Request.CreateResponse(HttpStatusCode.OK, result, Configuration.Formatters.JsonFormatter);
            }
        }
예제 #29
0
 internal void CacheBuildResult(string cacheKey, BuildResult result, DateTime utcStart)
 {
     CacheBuildResult(cacheKey, result, 0 /*hashCode*/, utcStart);
 }
예제 #30
0
        internal static bool CacheVPathBuildResult(VirtualPath virtualPath,
            BuildResult result, DateTime utcStart) {

            return _theBuildManager.CacheVPathBuildResultInternal(virtualPath, result, utcStart);
        }
예제 #31
0
    internal void SetBuildResultDependencies(BuildResult result) {

        result.AddVirtualPathDependencies(VirtualPathDependencies);
    }
예제 #32
0
 internal static bool CacheBuildResult(string cacheKey, BuildResult result, DateTime utcStart) {
     return _theBuildManager.CacheBuildResultInternal(cacheKey, result, 0 /*hashCode*/, utcStart);
 }
 internal void CacheBuildResult(string cacheKey, BuildResult result, DateTime utcStart)
 {
     this.CacheBuildResult(cacheKey, result, 0L, utcStart);
 }
예제 #34
0
    /*
     * Add a BuildResult's source dependencies to our own source dependencies
     */
    internal void AddBuildResultDependency(BuildResult result) {

        // Add one direct dependency
        if (_pageParserFilter != null)
            _pageParserFilter.OnDirectDependencyAdded();

        if (result.VirtualPathDependencies == null)
            return;

        foreach (string virtualPath in result.VirtualPathDependencies) {

            // Add one dependency for each file (to include direct and indirect)
            if (_pageParserFilter != null)
                _pageParserFilter.OnDependencyAdded();

            AddSourceDependency2(VirtualPath.Create(virtualPath));
        }
    }
예제 #35
0
        internal static Assembly GetCodeDirectoryAssembly(VirtualPath virtualDir,
                                                          CodeDirectoryType dirType, string assemblyName,
                                                          StringSet excludedSubdirectories, bool isDirectoryAllowed)
        {
            string physicalDir = virtualDir.MapPath();

            if (!isDirectoryAllowed)
            {
                // The directory should never exist in a precompiled app
                if (Directory.Exists(physicalDir))
                {
                    throw new HttpException(SR.GetString(SR.Bar_dir_in_precompiled_app, virtualDir));
                }
            }

            bool supportLocalization = IsResourceCodeDirectoryType(dirType);

            // Determine the proper cache key based on the type of directory we're processing
            string cacheKey = assemblyName;

            // Try the cache first
            BuildResult result         = BuildManager.GetBuildResultFromCache(cacheKey);
            Assembly    resultAssembly = null;

            // If it's cached, just return it
            if (result != null)
            {
                // It should always be a BuildResultCompiledAssembly, though if there is
                // a VirtualPathProvider doing very bad things, it may not (VSWhidbey 341701)
                Debug.Assert(result is BuildResultCompiledAssembly);
                if (result is BuildResultCompiledAssembly)
                {
                    // If it's the main code assembly, keep track of it so we can later call
                    // the AppInitialize method
                    if (result is BuildResultMainCodeAssembly)
                    {
                        Debug.Assert(dirType == CodeDirectoryType.MainCode);
                        Debug.Assert(_mainCodeBuildResult == null);
                        _mainCodeBuildResult = (BuildResultMainCodeAssembly)result;
                    }

                    resultAssembly = ((BuildResultCompiledAssembly)result).ResultAssembly;

                    if (!supportLocalization)
                    {
                        return(resultAssembly);
                    }

                    // We found a preserved resource assembly.  However, we may not be done,
                    // as the culture specific files may have changed.

                    // But don't make any further checks if the directory is not allowed (precomp secenario).
                    // In that case, we should always return the assembly (VSWhidbey 533498)
                    if (!isDirectoryAllowed)
                    {
                        return(resultAssembly);
                    }

                    BuildResultResourceAssembly buildResultResAssembly = (BuildResultResourceAssembly)result;

                    string newResourcesDependenciesHash = HashCodeCombiner.GetDirectoryHash(virtualDir);

                    // If the resources hash (which includes satellites) is up to date, we're done
                    if (newResourcesDependenciesHash == buildResultResAssembly.ResourcesDependenciesHash)
                    {
                        return(resultAssembly);
                    }
                }
            }

            // If app was precompiled, don't attempt compilation
            if (!isDirectoryAllowed)
            {
                return(null);
            }

            // Check whether the virtual dir is mapped to a different application,
            // which we don't support (VSWhidbey 218603).  But don't do this for LocalResource (VSWhidbey 237935)
            if (dirType != CodeDirectoryType.LocalResources && !StringUtil.StringStartsWithIgnoreCase(physicalDir, HttpRuntime.AppDomainAppPathInternal))
            {
                throw new HttpException(SR.GetString(SR.Virtual_codedir, virtualDir.VirtualPathString));
            }

            // If the directory doesn't exist, we may be done
            if (!Directory.Exists(physicalDir))
            {
                // We're definitely done if it's not the main code dir
                if (dirType != CodeDirectoryType.MainCode)
                {
                    return(null);
                }

                // If it is the main code dir, we're only done is there is no profile to compile
                // since the profice gets built as part of the main assembly.
                if (!ProfileBuildProvider.HasCompilableProfile)
                {
                    return(null);
                }
            }


            // Otherwise, compile it

            BuildManager.ReportDirectoryCompilationProgress(virtualDir);

            DateTime utcStart = DateTime.UtcNow;

            CodeDirectoryCompiler cdc = new CodeDirectoryCompiler(virtualDir,
                                                                  dirType, excludedSubdirectories);

            string outputAssemblyName = null;

            if (resultAssembly != null)
            {
                // If resultAssembly is not null, we are in the case where we just need to build
                // the localized resx file in a resources dir (local or global)
                Debug.Assert(supportLocalization);
                outputAssemblyName = resultAssembly.GetName().Name;
                cdc._onlyBuildLocalizedResources = true;
            }
            else
            {
                outputAssemblyName = BuildManager.GenerateRandomAssemblyName(assemblyName);
            }

            BuildProvidersCompiler bpc =
                new BuildProvidersCompiler(virtualDir, supportLocalization, outputAssemblyName);

            cdc._bpc = bpc;

            // Find all the build provider we want to compile from the code directory
            cdc.FindBuildProviders();

            // Give them to the BuildProvidersCompiler
            bpc.SetBuildProviders(cdc._buildProviders);

            // Compile them into an assembly
            CompilerResults results = bpc.PerformBuild();

            // Did we just compile something?
            if (results != null)
            {
                Debug.Assert(result == null);
                Debug.Assert(resultAssembly == null);

                // If there is already a loaded module with the same path, try to wait for it to be unloaded.
                // Otherwise, we would end up loading this old assembly instead of the new one (VSWhidbey 554697)
                DateTime waitLimit = DateTime.UtcNow.AddMilliseconds(3000);
                for (;;)
                {
                    IntPtr hModule = UnsafeNativeMethods.GetModuleHandle(results.PathToAssembly);
                    if (hModule == IntPtr.Zero)
                    {
                        break;
                    }

                    Debug.Trace("CodeDirectoryCompiler", results.PathToAssembly + " is already loaded. Waiting a bit");

                    System.Threading.Thread.Sleep(250);

                    // Stop trying if the timeout was reached
                    if (DateTime.UtcNow > waitLimit)
                    {
                        Debug.Trace("CodeDirectoryCompiler", "Timeout waiting for old assembly to unload: " + results.PathToAssembly);
                        throw new HttpException(SR.GetString(SR.Assembly_already_loaded, results.PathToAssembly));
                    }
                }

                resultAssembly = results.CompiledAssembly;
            }

            // It is possible that there was nothing to compile (and we're not in the
            // satellite resources case)
            if (resultAssembly == null)
            {
                return(null);
            }

            // For the main code directory, use a special BuildResult that takes care of
            // calling AppInitialize if it finds one
            if (dirType == CodeDirectoryType.MainCode)
            {
                // Keep track of it so we can later call the AppInitialize method
                _mainCodeBuildResult = new BuildResultMainCodeAssembly(resultAssembly);

                result = _mainCodeBuildResult;
            }
            else if (supportLocalization)
            {
                result = new BuildResultResourceAssembly(resultAssembly);
            }
            else
            {
                result = new BuildResultCompiledAssembly(resultAssembly);
            }

            result.VirtualPath = virtualDir;

            // If compilations are optimized, we need to include the right dependencies, since we can no longer
            // rely on everything getting wiped out when something in App_Code changes.
            // But don't do this for local resources, since they have their own special way of
            // dealing with dependencies (in BuildResultResourceAssembly.ComputeSourceDependenciesHashCode).
            // It's crucial *not* to do it as it triggers a tricky infinite recursion due to the fact
            // that GetBuildResultFromCacheInternal calls EnsureFirstTimeDirectoryInitForDependencies if
            // there is at least one dependency
            if (BuildManager.OptimizeCompilations && dirType != CodeDirectoryType.LocalResources)
            {
                result.AddVirtualPathDependencies(new SingleObjectCollection(virtualDir.AppRelativeVirtualPathString));
            }

            // Top level assembly should not be cached to memory.  But LocalResources are *not*
            // top level files, and do benefit from memory caching
            if (dirType != CodeDirectoryType.LocalResources)
            {
                result.CacheToMemory = false;
            }

            // Cache it for next time
            BuildManager.CacheBuildResult(cacheKey, result, utcStart);

            return(resultAssembly);
        }