Пример #1
0
        // gets a new set of elements
        // always creates a new set of elements,
        // even though the underlying elements may not change (store snapshots)
        public PublishedSnapshot.PublishedSnapshotElements GetElements(bool previewDefault)
        {
            EnsureCaches();

            // note: using ObjectCacheAppCache for elements and snapshot caches
            // is not recommended because it creates an inner MemoryCache which is a heavy
            // thing - better use a dictionary-based cache which "just" creates a concurrent
            // dictionary

            // for snapshot cache, DictionaryAppCache MAY be OK but it is not thread-safe,
            // nothing like that...
            // for elements cache, DictionaryAppCache is a No-No, use something better.
            // ie FastDictionaryAppCache (thread safe and all)
            ContentStore.Snapshot contentSnap, mediaSnap;
            SnapDictionary <int, Domain> .Snapshot domainSnap;
            IAppCache elementsCache;

            // Here we are reading/writing to shared objects so we need to lock (can't be _storesLock which manages the actual nucache files
            // and would result in a deadlock). Even though we are locking around underlying readlocks (within CreateSnapshot) it's because
            // we need to ensure that the result of contentSnap.Gen (etc) and the re-assignment of these values and _elements cache
            // are done atomically.

            lock (_elementsLock)
            {
                IScopeContext scopeContext = _scopeProvider.Context;

                if (scopeContext == null)
                {
                    contentSnap   = _contentStore.CreateSnapshot();
                    mediaSnap     = _mediaStore.CreateSnapshot();
                    domainSnap    = _domainStore.CreateSnapshot();
                    elementsCache = _elementsCache;
                }
                else
                {
                    contentSnap   = _contentStore.LiveSnapshot;
                    mediaSnap     = _mediaStore.LiveSnapshot;
                    domainSnap    = _domainStore.Test.LiveSnapshot;
                    elementsCache = _elementsCache;

                    // this is tricky
                    // we are returning elements composed from live snapshots, which we need to replace
                    // with actual snapshots when the context is gone - but when the action runs, there
                    // still is a context - so we cannot get elements - just resync = nulls the current
                    // elements
                    // just need to make sure nothing gets elements in another enlisted action... so using
                    // a MaxValue to make sure this one runs last, and it should be ok

                    scopeContext.Enlist("Umbraco.Web.PublishedCache.NuCache.PublishedSnapshotService.Resync", () => this, (completed, svc) =>
                    {
                        svc.CurrentPublishedSnapshot?.Resync();
                    }, int.MaxValue);
                }

                // create a new snapshot cache if snapshots are different gens
                if (contentSnap.Gen != _contentGen || mediaSnap.Gen != _mediaGen || domainSnap.Gen != _domainGen || _elementsCache == null)
                {
                    _contentGen   = contentSnap.Gen;
                    _mediaGen     = mediaSnap.Gen;
                    _domainGen    = domainSnap.Gen;
                    elementsCache = _elementsCache = new FastDictionaryAppCache();
                }
            }

            var snapshotCache = new DictionaryAppCache();

            var memberTypeCache = new PublishedContentTypeCache(null, null, _serviceContext.MemberTypeService, _publishedContentTypeFactory, _loggerFactory.CreateLogger <PublishedContentTypeCache>());

            var defaultCulture = _defaultCultureAccessor.DefaultCulture;
            var domainCache    = new DomainCache(domainSnap, defaultCulture);

            return(new PublishedSnapshot.PublishedSnapshotElements
            {
                ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainCache, Options.Create(_globalSettings), _variationContextAccessor),
                MediaCache = new MediaCache(previewDefault, mediaSnap, _variationContextAccessor),
                MemberCache = new MemberCache(previewDefault, memberTypeCache, _publishedSnapshotAccessor, _variationContextAccessor, _publishedModelFactory),
                DomainCache = domainCache,
                SnapshotCache = snapshotCache,
                ElementsCache = elementsCache
            });
        }