public void ScopeContextEnlistAgain(bool complete) { ScopeProvider scopeProvider = ScopeProvider; bool?completed = null; bool?completed2 = null; Assert.IsNull(scopeProvider.AmbientScope); using (IScope scope = scopeProvider.CreateScope()) { scopeProvider.Context.Enlist("name", c => { completed = c; // at that point the scope is gone, but the context is still there IScopeContext ambientContext = scopeProvider.AmbientContext; ambientContext.Enlist("another", c2 => completed2 = c2); }); if (complete) { scope.Complete(); } } Assert.IsNull(scopeProvider.AmbientScope); Assert.IsNull(scopeProvider.AmbientContext); Assert.IsNotNull(completed); Assert.AreEqual(complete, completed.Value); Assert.AreEqual(complete, completed2.Value); }
public static DeferedActions Get(IScopeProvider scopeProvider) { IScopeContext scopeContext = scopeProvider.Context; return(scopeContext?.Enlist("examineEvents", () => new DeferedActions(), // creator (completed, actions) => // action { if (completed) { actions.Execute(); } }, EnlistPriority)); }
// 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 }); }