コード例 #1
0
        /// <summary>
        /// When the page/content cache is refreshed, we'll check if any articulate root nodes were included in the refresh, if so we'll set a flag
        /// on the current request to rebuild the routes at the end of the request
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// This will also work for load balanced scenarios since this event executes on all servers
        /// </remarks>
        private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs e)
        {
            switch (e.MessageType)
            {
            case MessageType.RefreshById:
            case MessageType.RemoveById:
                var item = _umbracoContextAccessor?.UmbracoContext?.ContentCache.GetById((int)e.MessageObject);
                if (item != null && item.ContentType.Alias.InvariantEquals("Articulate"))
                {
                    //ensure routes are rebuilt
                    _appCaches.RequestCache.GetCacheItem("articulate-refresh-routes", () => true);
                }
                break;

            case MessageType.RefreshByInstance:
            case MessageType.RemoveByInstance:
                var content = e.MessageObject as IContent;
                if (content == null)
                {
                    return;
                }
                //TODO: There is a case when there are URL conflicts with Articulate data that when the other data is unpublished
                // we'd want to rebuild articulate routes, but not sure how to handle that and we don't want to rebuild everytime
                // something is unpublished
                if (content.ContentType.Alias.InvariantEquals("Articulate"))
                {
                    //ensure routes are rebuilt
                    _appCaches.RequestCache.GetCacheItem("articulate-refresh-routes", () => true);
                }
                break;
            }
        }
コード例 #2
0
    public override void Refresh(JsonPayload[] payloads)
    {
        // TODO: refactor
        // we should NOT directly clear caches here, but instead ask whatever class
        // is managing the cache to please clear that cache properly
        _contentTypeCommonRepository.ClearCache(); // always

        if (payloads.Any(x => x.ItemType == typeof(IContentType).Name))
        {
            ClearAllIsolatedCacheByEntityType <IContent>();
            ClearAllIsolatedCacheByEntityType <IContentType>();
        }

        if (payloads.Any(x => x.ItemType == typeof(IMediaType).Name))
        {
            ClearAllIsolatedCacheByEntityType <IMedia>();
            ClearAllIsolatedCacheByEntityType <IMediaType>();
        }

        if (payloads.Any(x => x.ItemType == typeof(IMemberType).Name))
        {
            ClearAllIsolatedCacheByEntityType <IMember>();
            ClearAllIsolatedCacheByEntityType <IMemberType>();
        }

        foreach (var id in payloads.Select(x => x.Id))
        {
            _idKeyMap.ClearCache(id);
        }

        if (payloads.Any(x => x.ItemType == typeof(IContentType).Name))
        {
            // don't try to be clever - refresh all
            ContentCacheRefresher.RefreshContentTypes(AppCaches);
        }

        if (payloads.Any(x => x.ItemType == typeof(IMediaType).Name))
        {
            // don't try to be clever - refresh all
            MediaCacheRefresher.RefreshMediaTypes(AppCaches);
        }

        if (payloads.Any(x => x.ItemType == typeof(IMemberType).Name))
        {
            // don't try to be clever - refresh all
            MemberCacheRefresher.RefreshMemberTypes(AppCaches);
        }

        // refresh the models and cache
        _publishedModelFactory.WithSafeLiveFactoryReset(() =>
                                                        _publishedSnapshotService.Notify(payloads));

        // now we can trigger the event
        base.Refresh(payloads);
    }
コード例 #3
0
        private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args)
        {
            if (args.MessageType != MessageType.RefreshByPayload)
            {
                return;
            }

            if (!_fullTextConfig.IsFullTextIndexingEnabled())
            {
                _logger.Debug <UpdateCacheOnPublish>("FullTextIndexing is not enabled");
                return;
            }

            if (!_examineManager.TryGetIndex("ExternalIndex", out IIndex index))
            {
                _logger.Error <UpdateCacheOnPublish>(new InvalidOperationException("No index found by name ExternalIndex"));
                return;
            }

            foreach (var payload in (ContentCacheRefresher.JsonPayload[])args.MessageObject)
            {
                if (payload.ChangeTypes.HasType(TreeChangeTypes.Remove))
                {
                    _cacheService.DeleteFromCache(payload.Id);
                }
                else if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll))
                {
                    // just ignore that payload (Umbracos examine implementation does the same)
                }
                else // RefreshNode or RefreshBranch (maybe trashed)
                {
                    _cacheService.AddCacheTask(payload.Id);

                    // branch
                    if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
                    {
                        const int pageSize = 500;
                        var       page     = 0;
                        var       total    = long.MaxValue;
                        while (page * pageSize < total)
                        {
                            var descendants = _contentService.GetPagedDescendants(payload.Id, page++, pageSize, out total,
                                                                                  //order by shallowest to deepest, this allows us to check it's published state without checking every item
                                                                                  ordering: Ordering.By("Path", Direction.Ascending));

                            foreach (var descendant in descendants)
                            {
                                _cacheService.AddCacheTask(descendant.Id);
                            }
                        }
                    }
                }
            }
        }
コード例 #4
0
        private void HandleCacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args)
        {
            if (args.MessageType != MessageType.RefreshByPayload)
            {
                return;
            }
            var payloads           = (ContentCacheRefresher.JsonPayload[])args.MessageObject;
            var hubContextInstance = _hubContext.Value;

            foreach (var payload in payloads)
            {
                var id = payload.Id; // keep it simple for now, ignore ChangeTypes
                hubContextInstance.Clients.All.refreshed(id);
            }
        }
コード例 #5
0
        /// <summary>
        /// Content cache was updated.
        /// </summary>
        private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher contentCacheRefresher,
                                                        CacheRefresherEventArgs e)
        {
            var kind = e.MessageType;

            if (kind == MessageType.RefreshById || kind == MessageType.RemoveById)
            {
                var id = e.MessageObject as int?;
                if (id.HasValue)
                {
                    var node = ContentService.GetById(id.Value);
                    if (node != null)
                    {
                        HandleChangedContent(new[] { node });
                    }
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// When the page/content cache is refreshed, we'll check if any articulate root nodes were included in the refresh, if so we'll set a flag
        /// on the current request to rebuild the routes at the end of the request
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// This will also work for load balanced scenarios since this event executes on all servers
        /// </remarks>
        private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs e)
        {
            switch (e.MessageType)
            {
            case MessageType.RefreshByPayload:
                //This is the standard case for content cache refresher
                foreach (var payload in (ContentCacheRefresher.JsonPayload[])e.MessageObject)
                {
                    if (payload.ChangeTypes.HasTypesAny(TreeChangeTypes.Remove | TreeChangeTypes.RefreshBranch | TreeChangeTypes.RefreshNode))
                    {
                        RefreshById(payload.Id);
                    }
                }
                break;

            case MessageType.RefreshById:
            case MessageType.RemoveById:
                RefreshById((int)e.MessageObject);
                break;

            case MessageType.RefreshByInstance:
            case MessageType.RemoveByInstance:
                var content = e.MessageObject as IContent;
                if (content == null)
                {
                    return;
                }
                //TODO: There is a case when there are URL conflicts with Articulate data that when the other data is unpublished
                // we'd want to rebuild articulate routes, but not sure how to handle that and we don't want to rebuild everytime
                // something is unpublished
                if (content.ContentType.Alias.InvariantEquals("Articulate"))
                {
                    //ensure routes are rebuilt
                    _appCaches.RequestCache.GetCacheItem("articulate-refresh-routes", () => true);
                }
                break;
            }
        }
コード例 #7
0
        /// <summary>
        /// When the page/content cache is refreshed, we'll check if any articulate root nodes were included in the refresh, if so we'll set a flag
        /// on the current request to rebuild the routes at the end of the request
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>
        /// This will also work for load balanced scenarios since this event executes on all servers
        /// </remarks>
        private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs e)
        {
            switch (e.MessageType)
            {
            case MessageType.RefreshByPayload:
                //This is the standard case for content cache refresher
                foreach (var payload in (ContentCacheRefresher.JsonPayload[])e.MessageObject)
                {
                    if (payload.ChangeTypes.HasTypesAny(TreeChangeTypes.Remove | TreeChangeTypes.RefreshBranch | TreeChangeTypes.RefreshNode))
                    {
                        RefreshById(payload.Id, payload.ChangeTypes);
                    }
                }
                break;

            case MessageType.RefreshById:
            case MessageType.RemoveById:
                RefreshById((int)e.MessageObject, TreeChangeTypes.Remove);
                break;

            case MessageType.RefreshByInstance:
            case MessageType.RemoveByInstance:
                var content = e.MessageObject as IContent;
                if (content == null)
                {
                    return;
                }

                if (content.ContentType.Alias.InvariantEquals(ArticulateContentTypeAlias))
                {
                    //ensure routes are rebuilt
                    _appCaches.RequestCache.GetCacheItem(RefreshRoutesToken, () => true);
                }
                break;
            }
        }
コード例 #8
0
        /// <summary>
        /// Updates indexes based on content changes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void ContentCacheRefresherUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs args)
        {
            if (Suspendable.ExamineEvents.CanIndex == false)
            {
                return;
            }

            if (args.MessageType != MessageType.RefreshByPayload)
            {
                throw new NotSupportedException();
            }

            var contentService = _services.ContentService;

            foreach (var payload in (ContentCacheRefresher.JsonPayload[])args.MessageObject)
            {
                if (payload.ChangeTypes.HasType(TreeChangeTypes.Remove))
                {
                    // delete content entirely (with descendants)
                    //  false: remove entirely from all indexes
                    DeleteIndexForEntity(payload.Id, false);
                }
                else if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll))
                {
                    // ExamineEvents does not support RefreshAll
                    // just ignore that payload
                    // so what?!

                    // TODO: Rebuild the index at this point?
                }
                else // RefreshNode or RefreshBranch (maybe trashed)
                {
                    // don't try to be too clever - refresh entirely
                    // there has to be race conditions in there ;-(

                    var content = contentService.GetById(payload.Id);
                    if (content == null)
                    {
                        // gone fishing, remove entirely from all indexes (with descendants)
                        DeleteIndexForEntity(payload.Id, false);
                        continue;
                    }

                    IContent published = null;
                    if (content.Published && contentService.IsPathPublished(content))
                    {
                        published = content;
                    }

                    if (published == null)
                    {
                        DeleteIndexForEntity(payload.Id, true);
                    }

                    // just that content
                    ReIndexForContent(content, published != null);

                    // branch
                    if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
                    {
                        var       masked   = published == null ? null : new List <int>();
                        const int pageSize = 500;
                        var       page     = 0;
                        var       total    = long.MaxValue;
                        while (page * pageSize < total)
                        {
                            var descendants = contentService.GetPagedDescendants(content.Id, page++, pageSize, out total,
                                                                                 //order by shallowest to deepest, this allows us to check it's published state without checking every item
                                                                                 ordering: Ordering.By("Path", Direction.Ascending));

                            foreach (var descendant in descendants)
                            {
                                published = null;
                                if (masked != null) // else everything is masked
                                {
                                    if (masked.Contains(descendant.ParentId) || !descendant.Published)
                                    {
                                        masked.Add(descendant.Id);
                                    }
                                    else
                                    {
                                        published = descendant;
                                    }
                                }

                                ReIndexForContent(descendant, published != null);
                            }
                        }
                    }
                }

                // NOTE
                //
                // DeleteIndexForEntity is handled by UmbracoContentIndexer.DeleteFromIndex() which takes
                //  care of also deleting the descendants
                //
                // ReIndexForContent is NOT taking care of descendants so we have to reload everything
                //  again in order to process the branch - we COULD improve that by just reloading the
                //  XML from database instead of reloading content & re-serializing!
                //
                // BUT ... pretty sure it is! see test "Index_Delete_Index_Item_Ensure_Heirarchy_Removed"
            }
        }
コード例 #9
0
        private void ContentCacheUpdated(ContentCacheRefresher sender, CacheRefresherEventArgs e)
        {
            if (!IsConfigured())
            {
                return;
            }

            var jsonPayloads = e.MessageObject as ContentCacheRefresher.JsonPayload[];

            if (jsonPayloads == null || !jsonPayloads.Any())
            {
                return;
            }

            var jobs = new List <EnterspeedJob>();

            using (var context = _umbracoContextFactory.EnsureUmbracoContext())
            {
                var umb = context.UmbracoContext;
                foreach (var payload in jsonPayloads)
                {
                    var node      = umb.Content.GetById(payload.Id);
                    var savedNode = umb.Content.GetById(true, payload.Id);
                    if (node == null || savedNode == null)
                    {
                        continue;
                    }

                    var cultures = node.ContentType.VariesByCulture()
                        ? node.Cultures.Keys
                        : new List <string> {
                        GetDefaultCulture(context)
                    };

                    List <IPublishedContent> descendants = null;

                    foreach (var culture in cultures)
                    {
                        var publishedUpdateDate = node.CultureDate(culture);
                        var savedUpdateDate     = savedNode.CultureDate(culture);

                        if (savedUpdateDate > publishedUpdateDate)
                        {
                            // This means that the nodes was only saved, so we skip creating any jobs for this node and culture
                            continue;
                        }

                        var now = DateTime.UtcNow;
                        jobs.Add(new EnterspeedJob
                        {
                            ContentId = node.Id,
                            Culture   = culture,
                            JobType   = EnterspeedJobType.Publish,
                            State     = EnterspeedJobState.Pending,
                            CreatedAt = now,
                            UpdatedAt = now,
                        });

                        if (payload.ChangeTypes == TreeChangeTypes.RefreshBranch)
                        {
                            if (descendants == null)
                            {
                                descendants = node.Descendants("*").ToList();
                            }

                            foreach (var descendant in descendants)
                            {
                                var descendantCultures = descendant.ContentType.VariesByCulture()
                                    ? descendant.Cultures.Keys
                                    : new List <string> {
                                    GetDefaultCulture(context)
                                };

                                foreach (var descendantCulture in descendantCultures)
                                {
                                    jobs.Add(new EnterspeedJob
                                    {
                                        ContentId = descendant.Id,
                                        Culture   = descendantCulture,
                                        JobType   = EnterspeedJobType.Publish,
                                        State     = EnterspeedJobState.Pending,
                                        CreatedAt = now,
                                        UpdatedAt = now,
                                    });
                                }
                            }
                        }
                    }
                }
            }

            EnqueueJobs(jobs);
        }
コード例 #10
0
        private void SyncZeroValuePaymentProviderContinueUrl(ContentCacheRefresher sender, CacheRefresherEventArgs e)
        {
            var payloads = e.MessageObject as ContentCacheRefresher.JsonPayload[];

            if (payloads == null)
            {
                return;
            }

            using (var umbNew = _umbracoContextFactory.EnsureUmbracoContext())
            {
                foreach (var payload in payloads)
                {
                    if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshNode))
                    {
                        // Single node refresh

                        var node = umbNew.UmbracoContext.Content.GetById(payload.Id);
                        if (node != null && IsConfirmationPageType(node))
                        {
                            SyncZeroValuePaymentProviderContinueUrl(node);
                        }
                    }
                    else if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshBranch))
                    {
                        // Branch refresh

                        var rootNode = umbNew.UmbracoContext.Content.GetById(payload.Id);
                        if (rootNode != null)
                        {
                            var nodeType = umbNew.UmbracoContext.Content.GetContentType(VendrCheckoutConstants.ContentTypes.Aliases.CheckoutStepPage);
                            if (nodeType == null)
                            {
                                continue;
                            }

                            var nodes = umbNew.UmbracoContext.Content.GetByContentType(nodeType);

                            foreach (var node in nodes?.Where(x => IsConfirmationPageType(x) && x.Path.StartsWith(rootNode.Path)))
                            {
                                SyncZeroValuePaymentProviderContinueUrl(node);
                            }
                        }
                    }
                    else if (payload.ChangeTypes.HasType(TreeChangeTypes.RefreshAll))
                    {
                        // All refresh

                        var nodeType = umbNew.UmbracoContext.Content.GetContentType(VendrCheckoutConstants.ContentTypes.Aliases.CheckoutStepPage);
                        if (nodeType == null)
                        {
                            continue;
                        }

                        var nodes = umbNew.UmbracoContext.Content.GetByContentType(nodeType);

                        foreach (var node in nodes?.Where(x => IsConfirmationPageType(x)))
                        {
                            SyncZeroValuePaymentProviderContinueUrl(node);
                        }
                    }
                }
            }
        }
コード例 #11
0
 private void ContentCacheRefresher_CacheUpdated(ContentCacheRefresher sender, Umbraco.Core.Cache.CacheRefresherEventArgs e)
 {
     Cache.Instance.RemoveByPrefix(typeof(CmsServiceCachedProxy).ToString());
 }