// ========================================================================== // RedisPubSub.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== using System; using System.Collections.Concurrent; using Squidex.Infrastructure.Log; using StackExchange.Redis; namespace Squidex.Infrastructure { public class RedisPubSub : IPubSub, IExternalSystem { private readonly ConcurrentDictionary subscriptions = new ConcurrentDictionary(); private readonly Lazy redisClient; private readonly Lazy redisSubscriber; private readonly ISemanticLog log; public RedisPubSub(Lazy redis, ISemanticLog log) { Guard.NotNull(redis, nameof(redis)); Guard.NotNull(log, nameof(log)); this.log = log; redisClient = redis; redisSubscriber = new Lazy(() => redis.Value.GetSubscriber()); } public void Connect() { try { redisClient.Value.GetStatus(); } catch (Exception ex) { throw new ConfigurationException($"Redis connection failed to connect to database {redisClient.Value.Configuration}", ex); } } public void Publish(string channelName, string token, bool notifySelf) { Guard.NotNullOrEmpty(channelName, nameof(channelName)); subscriptions.GetOrAdd(channelName, c => new RedisSubscription(redisSubscriber.Value, c, log)).Publish(token, notifySelf); } public IDisposable Subscribe(string channelName, Action handler) { Guard.NotNullOrEmpty(channelName, nameof(channelName)); return subscriptions.GetOrAdd(channelName, c => new RedisSubscription(redisSubscriber.Value, c, log)).Subscribe(handler); } } }