Service Bus and Event broker

Hi,
We have installed a service bus on a Litium 7 environment. Set up connection string on all environments. But now, the event brokers subscriptions is only working on the changed environments. Do we need to add anything so that, when a category is updated, all environments will run the subscription events?

Litium version: 7

Hi,
What is your subscriber idoing, updating some cache? Then you have to write your eventbroker to propagate it to other subscribers since all the events are local.

Yes. For the CategoryFilterService to clear the cache(singleton property) when a category is updated.
Do you have any examples for this?

No, i dont have a ready-made but i’ll fix one for you.

1 Like

Not sure what cache you are using but if you use the Litium.Caching.MemoryCacheService an event is automatic propagated to all applications to remove the item from the cache when you call the Remove(string) method.

Has your problem been solved by Patric’s suggestion or do you still want to have some sample code?

I will try with this. But it will be good to get some sample code, because I would need a logic on other instances as well

The subscriptions Jinesh is talking about is from the Accelerator in Litium.Accelerator.Search.Filtering.CategoryFilterService. Are you saying that this implementation does not handle event propagation among multiple applications?

Reading the documentation at https://docs.litium.com/documentation/architecture/events-handling one could get the idea that it’s built-in: “The event broker is used to handle events. When using multiple applications, web farms or multiple developers with the same database, the event synchronization between all applications are made with a service bus.”

When looking at the implementation it looks like it not propagating the cache removal to other servers. Please, create a bug on docs.

In general the events that is triggered by Litium is only raised on the same application and the cachen that will be flushed by the event will trigger another event that is replicated to all servers to remove the item from the cache.

1 Like

Bug #47083 reported.

1 Like

Updated CategoryFilterService

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Litium.Accelerator.Constants;
using Litium.Common.Events;
using Litium.Events;
using Litium.FieldFramework.Events;
using Litium.Foundation.Modules.ExtensionMethods;
using Litium.Products.Events;
using Litium.Runtime;
using Litium.Runtime.DependencyInjection;

namespace Litium.Accelerator.Search.Filtering
{
    [Autostart]
    [Service(ServiceType = typeof(CategoryFilterService), Lifetime = DependencyLifetime.Singleton)]
    public class CategoryFilterService
    {
        private readonly ConcurrentDictionary<Guid, string[]> _cache = new ConcurrentDictionary<Guid, string[]>();
        private readonly FilterService _filterService;

        public CategoryFilterService(EventBroker eventBroker, FilterService filterService)
        {
            _filterService = filterService;

            eventBroker.Subscribe<PurgeFilterCache>(_ => _cache.Clear());
            eventBroker.Subscribe<CategoryCreated>(_ => ClearCache());
            eventBroker.Subscribe<CategoryDeleted>(_ => ClearCache());
            eventBroker.Subscribe<CategoryUpdated>(_ => ClearCache());
            eventBroker.Subscribe<FieldDefinitionCreated>(_ => ClearCache());
            eventBroker.Subscribe<FieldDefinitionDeleted>(_ => ClearCache());
            eventBroker.Subscribe<FieldDefinitionUpdated>(_ => ClearCache());
            eventBroker.Subscribe<SettingChanged>(x =>
            {
                if (FilterService._key == x.Key && x.PersonSystemId == Guid.Empty)
                {
                    ClearCache();
                }
            });

            void ClearCache()
            {
                _cache.Clear();
                eventBroker.Publish(EventScope.Remote, new PurgeFilterCache());
            }
        }

        public string[] GetFilters(Guid categorySystemId)
        {
            return _cache.GetOrAdd(categorySystemId, key =>
            {
                var filterFields = _filterService.GetProductFilteringFields();
                var customFilters = GetCustomFilterValues(key);
                return customFilters != null ? filterFields.Intersect(customFilters, StringComparer.OrdinalIgnoreCase).ToArray() : (filterFields?.ToArray() ?? new string[0]);
            });
        }

        private static IList<string> GetCustomFilterValues(Guid categorySystemId)
        {
            var category = categorySystemId.GetCategory();
            while (category != null)
            {
                var customFilterOptions = category.Fields.GetValue<IList<string>>(NavigationConstants.AcceleratorFilterFieldDefinitionName);
                if (customFilterOptions != null)
                {
                    return customFilterOptions;
                }

                if (category.ParentCategorySystemId == Guid.Empty)
                {
                    break;
                }

                category = category.ParentCategorySystemId.GetCategory();
            }

            return null;
        }

        private class PurgeFilterCache : IMessage { }
    }
}

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.