private void UmbracoModule_RouteAttempt(object sender, RoutableAttemptEventArgs e) { if (!_initialized) { lock (_locker) { // double check lock, we must only do this once if (!_initialized) { _initialized = true; UmbracoModule.RouteAttempt -= UmbracoModule_RouteAttempt; if (!_mainDom.IsMainDom) { return; } var bootState = _syncBootStateAccessor.GetSyncBootState(); _examineManager.ConfigureIndexes(_mainDom, _logger); // if it's a cold boot, rebuild all indexes including non-empty ones // delay one minute since a cold boot also triggers nucache rebuilds _indexRebuilder.RebuildIndexes(bootState != SyncBootState.ColdBoot, 60000); } } } }
// <summary> /// Initializes a server that has never synchronized before. /// </summary> /// <remarks> /// Thread safety: this is NOT thread safe. Because it is NOT meant to run multi-threaded. /// Callers MUST ensure thread-safety. /// </remarks> private SyncBootState InitializeColdBootState() { lock (_locko) { if (_cancellationToken.IsCancellationRequested) { return(SyncBootState.Unknown); } SyncBootState syncState = _syncBootStateAccessor.GetSyncBootState(); if (syncState == SyncBootState.ColdBoot) { // Get the last id in the db and store it. // Note: Do it BEFORE initializing otherwise some instructions might get lost // when doing it before. Some instructions might run twice but this is not an issue. var maxId = CacheInstructionService.GetMaxInstructionId(); // if there is a max currently, or if we've never synced if (maxId > 0 || _lastSyncedFileManager.LastSyncedId < 0) { _lastSyncedFileManager.SaveLastSyncedId(maxId); } } return(syncState); } }
/// <summary> /// On first http request schedule an index rebuild for any empty indexes (or all if it's a cold boot) /// </summary> /// <param name="notification"></param> public void Handle(UmbracoRequestBeginNotification notification) { if (_runtimeState.Level != RuntimeLevel.Run) { return; } LazyInitializer.EnsureInitialized( ref _isReady, ref _isReadSet, ref _isReadyLock, () => { SyncBootState bootState = _syncBootStateAccessor.GetSyncBootState(); _backgroundIndexRebuilder.RebuildIndexes( // if it's not a cold boot, only rebuild empty ones bootState != SyncBootState.ColdBoot, TimeSpan.FromMinutes(1)); return(true); }); }
/// <summary> /// Lazily populates the stores only when they are first requested /// </summary> internal void EnsureCaches() => LazyInitializer.EnsureInitialized( ref _isReady, ref _isReadSet, ref _isReadyLock, () => { // lock this entire call, we only want a single thread to be accessing the stores at once and within // the call below to mainDom.Register, a callback may occur on a threadpool thread to MainDomRelease // at the same time as we are trying to write to the stores. MainDomRelease also locks on _storesLock so // it will not be able to close the stores until we are done populating (if the store is empty) lock (_storesLock) { if (!_options.IgnoreLocalDb) { _mainDom.Register(MainDomRegister, MainDomRelease); // stores are created with a db so they can write to it, but they do not read from it, // stores need to be populated, happens in OnResolutionFrozen which uses _localDbExists to // figure out whether it can read the databases or it should populate them from sql _logger.LogInformation("Creating the content store, localContentDbExists? {LocalContentDbExists}", _localContentDbExists); _contentStore = new ContentStore(_publishedSnapshotAccessor, _variationContextAccessor, _loggerFactory.CreateLogger("ContentStore"), _loggerFactory, _publishedModelFactory, _localContentDb); _logger.LogInformation("Creating the media store, localMediaDbExists? {LocalMediaDbExists}", _localMediaDbExists); _mediaStore = new ContentStore(_publishedSnapshotAccessor, _variationContextAccessor, _loggerFactory.CreateLogger("ContentStore"), _loggerFactory, _publishedModelFactory, _localMediaDb); } else { _logger.LogInformation("Creating the content store (local db ignored)"); _contentStore = new ContentStore(_publishedSnapshotAccessor, _variationContextAccessor, _loggerFactory.CreateLogger("ContentStore"), _loggerFactory, _publishedModelFactory); _logger.LogInformation("Creating the media store (local db ignored)"); _mediaStore = new ContentStore(_publishedSnapshotAccessor, _variationContextAccessor, _loggerFactory.CreateLogger("ContentStore"), _loggerFactory, _publishedModelFactory); } _domainStore = new SnapDictionary <int, Domain>(); var okContent = false; var okMedia = false; SyncBootState bootState = _syncBootStateAccessor.GetSyncBootState(); try { if (bootState != SyncBootState.ColdBoot && _localContentDbExists) { okContent = LockAndLoadContent(() => LoadContentFromLocalDbLocked(true)); if (!okContent) { _logger.LogWarning("Loading content from local db raised warnings, will reload from database."); } } if (bootState != SyncBootState.ColdBoot && _localMediaDbExists) { okMedia = LockAndLoadMedia(() => LoadMediaFromLocalDbLocked(true)); if (!okMedia) { _logger.LogWarning("Loading media from local db raised warnings, will reload from database."); } } if (!okContent) { LockAndLoadContent(() => LoadContentFromDatabaseLocked(true)); } if (!okMedia) { LockAndLoadMedia(() => LoadMediaFromDatabaseLocked(true)); } LockAndLoadDomains(); } catch (Exception ex) { _logger.LogCritical(ex, "Panic, exception while loading cache data."); throw; } return(true); } });