Пример #1
0
    private void DetermineRuntimeLevel()
    {
        if (State.BootFailedException is not null)
        {
            // There's already been an exception, so cannot boot and no need to check
            return;
        }

        using DisposableTimer? timer =
                  _profilingLogger.DebugDuration <CoreRuntime>("Determining runtime level.", "Determined.");

        try
        {
            State.DetermineRuntimeLevel();

            _logger.LogDebug("Runtime level: {RuntimeLevel} - {RuntimeLevelReason}", State.Level, State.Reason);

            if (State.Level == RuntimeLevel.Upgrade)
            {
                _logger.LogDebug("Configure database factory for upgrades.");
                _databaseFactory.ConfigureForUpgrade();
            }
        }
        catch (Exception ex)
        {
            State.Configure(RuntimeLevel.BootFailed, RuntimeLevelReason.BootFailedOnException);
            timer?.Fail();
            _logger.LogError(ex, "Boot Failed");

            // We do not throw the exception, it will be rethrown by BootFailedMiddleware
        }
    }
Пример #2
0
    private void AcquireMainDom()
    {
        using DisposableTimer? timer = _profilingLogger.DebugDuration <CoreRuntime>("Acquiring MainDom.", "Acquired.");

        try
        {
            _mainDom.Acquire(_applicationShutdownRegistry);
        }
        catch
        {
            timer?.Fail();
            throw;
        }
    }
Пример #3
0
        /// <summary>
        /// Boots the runtime within a timer.
        /// </summary>
        protected virtual IFactory Boot(IRegister register, DisposableTimer timer)
        {
            Composition composition = null;

            try
            {
                // Setup event listener
                UnattendedInstalled += CoreRuntime_UnattendedInstalled;

                // throws if not full-trust
                new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand();

                // run handlers
                RuntimeOptions.DoRuntimeBoot(ProfilingLogger);

                // application caches
                var appCaches = GetAppCaches();

                // database factory
                var databaseFactory = GetDatabaseFactory();

                // configs
                var configs = GetConfigs();

                // type loader
                var typeLoader = new TypeLoader(appCaches.RuntimeCache, configs.Global().LocalTempPath, ProfilingLogger);

                // runtime state
                // beware! must use '() => _factory.GetInstance<T>()' and NOT '_factory.GetInstance<T>'
                // as the second one captures the current value (null) and therefore fails
                _state = new RuntimeState(Logger,
                                          configs.Settings(), configs.Global(),
                                          new Lazy <IMainDom>(() => _factory.GetInstance <IMainDom>()),
                                          new Lazy <IServerRegistrar>(() => _factory.GetInstance <IServerRegistrar>()))
                {
                    Level = RuntimeLevel.Boot
                };

                // TODO: remove this in netcore, this is purely backwards compat hacks with the empty ctor
                if (MainDom == null)
                {
                    MainDom = new MainDom(Logger, new MainDomSemaphoreLock(Logger));
                }


                // create the composition
                composition = new Composition(register, typeLoader, ProfilingLogger, _state, configs);
                composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, MainDom, appCaches, databaseFactory, typeLoader, _state);

                // run handlers
                RuntimeOptions.DoRuntimeEssentials(composition, appCaches, typeLoader, databaseFactory);



                // register runtime-level services
                // there should be none, really - this is here "just in case"
                Compose(composition);

                // acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
                AcquireMainDom(MainDom);

                // determine our runtime level
                DetermineRuntimeLevel(databaseFactory, ProfilingLogger);

                // get composers, and compose
                var composerTypes = ResolveComposerTypes(typeLoader);

                IEnumerable <Attribute> enableDisableAttributes;
                using (ProfilingLogger.DebugDuration <CoreRuntime>("Scanning enable/disable composer attributes"))
                {
                    enableDisableAttributes = typeLoader.GetAssemblyAttributes(typeof(EnableComposerAttribute), typeof(DisableComposerAttribute));
                }

                var composers = new Composers(composition, composerTypes, enableDisableAttributes, ProfilingLogger);
                composers.Compose();

                // create the factory
                _factory = Current.Factory = composition.CreateFactory();

                // determines if unattended install is enabled and performs it if required
                DoUnattendedInstall(databaseFactory);

                // determine our runtime level (AFTER UNATTENDED INSTALL)
                // TODO: Feels kinda weird to call this again
                DetermineRuntimeLevel(databaseFactory, ProfilingLogger);

                // if level is Run and reason is UpgradeMigrations, that means we need to perform an unattended upgrade
                if (_state.Reason == RuntimeLevelReason.UpgradeMigrations && _state.Level == RuntimeLevel.Run)
                {
                    // do the upgrade
                    DoUnattendedUpgrade(_factory.GetInstance <DatabaseBuilder>());

                    // upgrade is done, set reason to Run
                    _state.Reason = RuntimeLevelReason.Run;
                }

                // create & initialize the components
                _components = _factory.GetInstance <ComponentCollection>();
                _components.Initialize();
            }
            catch (Exception e)
            {
                var bfe = e as BootFailedException ?? new BootFailedException("Boot failed.", e);

                if (_state != null)
                {
                    _state.Level = RuntimeLevel.BootFailed;
                    _state.BootFailedException = bfe;
                }

                timer?.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves

                // if something goes wrong above, we may end up with no factory
                // meaning nothing can get the runtime state, etc - so let's try
                // to make sure we have a factory
                if (_factory == null)
                {
                    try
                    {
                        _factory = Current.Factory = composition?.CreateFactory();
                    }
                    catch
                    {
                        // In this case we are basically dead, we do not have a factory but we need
                        // to report on the state so we need to manually set that, this is the only time
                        // we ever do this.
                        Current.RuntimeState = _state;
                    }
                }

                Debugger.Break();

                // throwing here can cause w3wp to hard-crash and we want to avoid it.
                // instead, we're logging the exception and setting level to BootFailed.
                // various parts of Umbraco such as UmbracoModule and UmbracoDefaultOwinStartup
                // understand this and will nullify themselves, while UmbracoModule will
                // throw a BootFailedException for every requests.
            }

            return(_factory);
        }
Пример #4
0
        /// <summary>
        /// Boots the runtime within a timer.
        /// </summary>
        protected virtual IFactory Boot(IRegister register, DisposableTimer timer)
        {
            Composition composition = null;

            try
            {
                // throws if not full-trust
                new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand();

                // application caches
                var appCaches    = GetAppCaches();
                var runtimeCache = appCaches.RuntimeCache;

                // database factory
                var databaseFactory = GetDatabaseFactory();

                // configs
                var configs = GetConfigs();

                // type loader
                var localTempStorage = configs.Global().LocalTempStorageLocation;
                var typeLoader       = new TypeLoader(runtimeCache, localTempStorage, ProfilingLogger);

                // runtime state
                // beware! must use '() => _factory.GetInstance<T>()' and NOT '_factory.GetInstance<T>'
                // as the second one captures the current value (null) and therefore fails
                _state = new RuntimeState(Logger,
                                          configs.Settings(), configs.Global(),
                                          new Lazy <IMainDom>(() => _factory.GetInstance <IMainDom>()),
                                          new Lazy <IServerRegistrar>(() => _factory.GetInstance <IServerRegistrar>()))
                {
                    Level = RuntimeLevel.Boot
                };

                // main dom
                var mainDom = new MainDom(Logger);

                // create the composition
                composition = new Composition(register, typeLoader, ProfilingLogger, _state, configs);
                composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, mainDom, appCaches, databaseFactory, typeLoader, _state);

                // register runtime-level services
                // there should be none, really - this is here "just in case"
                Compose(composition);

                // acquire the main domain, determine our runtime level
                AcquireMainDom(mainDom);
                DetermineRuntimeLevel(databaseFactory, ProfilingLogger);

                // get composers, and compose
                var composerTypes = ResolveComposerTypes(typeLoader);
                composition.WithCollectionBuilder <ComponentCollectionBuilder>();
                var composers = new Composers(composition, composerTypes, ProfilingLogger);
                composers.Compose();

                // create the factory
                _factory = Current.Factory = composition.CreateFactory();

                // create & initialize the components
                _components = _factory.GetInstance <ComponentCollection>();
                _components.Initialize();
            }
            catch (Exception e)
            {
                var bfe = e as BootFailedException ?? new BootFailedException("Boot failed.", e);

                if (_state != null)
                {
                    _state.Level = RuntimeLevel.BootFailed;
                    _state.BootFailedException = bfe;
                }

                timer.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves

                // if something goes wrong above, we may end up with no factory
                // meaning nothing can get the runtime state, etc - so let's try
                // to make sure we have a factory
                if (_factory == null)
                {
                    try
                    {
                        _factory = Current.Factory = composition?.CreateFactory();
                    }
                    catch { /* yea */ }
                }

                Debugger.Break();

                // throwing here can cause w3wp to hard-crash and we want to avoid it.
                // instead, we're logging the exception and setting level to BootFailed.
                // various parts of Umbraco such as UmbracoModule and UmbracoDefaultOwinStartup
                // understand this and will nullify themselves, while UmbracoModule will
                // throw a BootFailedException for every requests.
            }

            return(_factory);
        }