[System.Web.Http.HttpPost] // use the http one, not mvc, with api controllers! public HttpResponseMessage BuildModels() { try { if (!UmbracoConfig.For.ModelsBuilder().ModelsMode.SupportsExplicitGeneration()) { var result2 = new BuildResult { Success = false, Message = "Models generation is not enabled." }; return(Request.CreateResponse(HttpStatusCode.OK, result2, Configuration.Formatters.JsonFormatter)); } var modelsDirectory = UmbracoConfig.For.ModelsBuilder().ModelsDirectory; 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(modelsDirectory, UmbracoConfig.For.ModelsBuilder().ModelsMode.IsAnyDll() ? bin : null); ModelsGenerationError.Clear(); } catch (Exception e) { ModelsGenerationError.Report("Failed to build models.", e); } return(Request.CreateResponse(HttpStatusCode.OK, GetDashboardResult(), Configuration.Formatters.JsonFormatter)); }
public static void GenerateModelsIfRequested(object sender, EventArgs args) { //if (HttpContext.Current.Items[this] == null) return; if (Interlocked.Exchange(ref _req, 0) == 0) { return; } // cannot use a simple lock here because we don't want another AppDomain // to generate while we do... and there could be 2 AppDomains if the app restarts. try { LogHelper.Debug <LiveModelsProvider>("Generate models..."); const int timeout = 2 * 60 * 1000; // 2 mins _mutex.WaitOne(timeout); // wait until it is safe, and acquire LogHelper.Info <LiveModelsProvider>("Generate models now."); GenerateModels(); ModelsGenerationError.Clear(); LogHelper.Info <LiveModelsProvider>("Generated."); } catch (TimeoutException) { LogHelper.Warn <LiveModelsProvider>("Timeout, models were NOT generated."); } catch (Exception e) { ModelsGenerationError.Report("Failed to build Live models.", e); LogHelper.Error <LiveModelsProvider>("Failed to generate models.", e); } finally { _mutex.ReleaseMutex(); // release } }
// ensure that the factory is running with the lastest generation of models internal Infos EnsureModels() { if (_debugLevel > 0) { _logger.Logger.Debug <PureLiveModelFactory>("Ensuring models."); } // don't use an upgradeable lock here because only 1 thread at a time could enter it try { _locker.EnterReadLock(); if (_hasModels) { return(_infos); } } finally { if (_locker.IsReadLockHeld) { _locker.ExitReadLock(); } } var buildManagerLocked = false; try { // always take the BuildManager lock *before* taking the _locker lock // to avoid possible deadlock situations (see notes above) Monitor.Enter(TheBuildManager, ref buildManagerLocked); _locker.EnterUpgradeableReadLock(); if (_hasModels) { return(_infos); } _locker.EnterWriteLock(); // we don't have models, // either they haven't been loaded from the cache yet // or they have been reseted and are pending a rebuild using (_logger.DebugDuration <PureLiveModelFactory>("Get models.", "Got models.")) { try { var assembly = GetModelsAssembly(_pendingRebuild); // the one below can be used to simulate an issue with BuildManager, ie it will register // the models with the factory but NOT with the BuildManager, which will not recompile views. // this is for U4-8043 which is an obvious issue but I cannot replicate //_modelsAssembly = _modelsAssembly ?? assembly; // the one below is the normal one _modelsAssembly = assembly; var types = assembly.ExportedTypes.Where(x => x.Inherits <PublishedContentModel>() || x.Inherits <PublishedElementModel>()); _infos = RegisterModels(types); ModelsGenerationError.Clear(); } catch (Exception e) { try { _logger.Logger.Error <PureLiveModelFactory>("Failed to build models.", e); _logger.Logger.Warn <PureLiveModelFactory>("Running without models."); // be explicit ModelsGenerationError.Report("Failed to build PureLive models.", e); } finally { _modelsAssembly = null; _infos = new Infos { ModelInfos = null, ModelTypeMap = new Dictionary <string, Type>() }; } } // don't even try again _hasModels = true; } return(_infos); } finally { if (_locker.IsWriteLockHeld) { _locker.ExitWriteLock(); } if (_locker.IsUpgradeableReadLockHeld) { _locker.ExitUpgradeableReadLock(); } if (buildManagerLocked) { Monitor.Exit(TheBuildManager); } } }
// ensure that the factory is running with the lastest generation of models internal Dictionary <string, Func <IPublishedContent, IPublishedContent> > EnsureModels() { _logger.Logger.Debug <PureLiveModelFactory>("Ensuring models."); _locker.EnterReadLock(); try { if (_hasModels) { return(_constructors); } } finally { _locker.ExitReadLock(); } _locker.EnterWriteLock(); try { if (_hasModels) { return(_constructors); } // we don't have models, // either they haven't been loaded from the cache yet // or they have been reseted and are pending a rebuild using (_logger.DebugDuration <PureLiveModelFactory>("Get models.", "Got models.")) { try { var assembly = GetModelsAssembly(_pendingRebuild); // the one below can be used to simulate an issue with BuildManager, ie it will register // the models with the factory but NOT with the BuildManager, which will not recompile views. // this is for U4-8043 which is an obvious issue but I cannot replicate //_modelsAssembly = _modelsAssembly ?? assembly; // the one below is the normal one _modelsAssembly = assembly; var types = assembly.ExportedTypes.Where(x => x.Inherits <PublishedContentModel>()); _constructors = RegisterModels(types); ModelsGenerationError.Clear(); } catch (Exception e) { _logger.Logger.Error <PureLiveModelFactory>("Failed to build models.", e); _logger.Logger.Warn <PureLiveModelFactory>("Running without models."); // be explicit ModelsGenerationError.Report("Failed to build PureLive models.", e); _modelsAssembly = null; _constructors = null; } _hasModels = true; } return(_constructors); } finally { _locker.ExitWriteLock(); } }