Advertisement
Guest User

Untitled

a guest
Aug 26th, 2018
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.16 KB | None | 0 0
  1.    [RegisterSingletonToDi]
  2.      public class CacheInvalidationWorker
  3.     {
  4.         private static readonly CacheKeyMappingStorage CacheKeysMappingStorage = new CacheKeyMappingStorage();
  5.         private readonly RabbitMQConnectionOptions _options;
  6.         private IConnection _conn;
  7.         private static IMemoryCache _cache;
  8.         private IModel _channel;
  9.  
  10.  
  11.         public CacheInvalidationWorker(
  12.             IOptions<RabbitMQConnectionOptions> options,
  13.             IMemoryCache cache)
  14.         {
  15.             _options = options.Value;
  16.             _cache = cache;
  17.             Consume();
  18.         }
  19.  
  20.         public static void AddCacheKeyMapping(string key, string value = null)
  21.         {
  22.             CacheKeysMappingStorage.Add(key, value ?? key);
  23.         }
  24.  
  25.         private bool ConnectToRabbitMq()
  26.         {
  27.            
  28.             _conn?.Dispose();
  29.             _channel?.Dispose();
  30.             try
  31.             {
  32.                 var factory = new ConnectionFactory
  33.                 {
  34.                     UserName = _options.UserName,
  35.                     Password = _options.Passwd,
  36.                     VirtualHost = _options.VirtualHost,
  37.                     HostName = _options.Host
  38.                 };
  39.                 _conn = factory.CreateConnection();
  40.                 _channel = _conn.CreateModel();
  41.                 return true;
  42.             }
  43.             catch (System.IO.EndOfStreamException ex)
  44.             {
  45.                 Console.WriteLine(ex);
  46.             }
  47.             catch (BrokerUnreachableException ex)
  48.             {
  49.                 Console.WriteLine(ex);
  50.             }
  51.             return false;
  52.         }
  53.  
  54.         private void Consume()
  55.         {
  56.             ConnectToRabbitMq();
  57.  
  58.             _channel.ExchangeDeclare("cache_invalidation", "fanout");
  59.             var queueName = _channel.QueueDeclare().QueueName;
  60.  
  61.             _channel.QueueBind(queueName,"cache_invalidation",string.Empty);
  62.  
  63.             var consumer = new EventingBasicConsumer(_channel);
  64.             consumer.Received += (model, ea) =>
  65.             {
  66.                 var body = ea.Body;
  67.                 var msg = LZ4MessagePackSerializer.Deserialize<string>(
  68.                     body,
  69.                     MessagePack.Resolvers.ContractlessStandardResolver.Instance);              
  70.                 RemoveFromCache(msg);
  71.             };
  72.  
  73.             consumer.Shutdown += (o, e) =>
  74.             {
  75.                 Consume();
  76.             };
  77.             _channel.BasicConsume(queueName,true,consumer);
  78.         }
  79.  
  80.         private static void RemoveFromCache(string keyMapping)
  81.         {
  82.             if (!CacheKeysMappingStorage.TryRemove(keyMapping, out var keys))
  83.             {
  84.                 return;
  85.             }
  86.  
  87.             foreach (var key in keys)
  88.             {
  89.                 _cache.Remove(key.Key);
  90.             }
  91.         }
  92.     }  
  93.  
  94.     public class CacheKeyMappingStorage
  95.     {
  96.         private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, byte>> _straightMapping =
  97.             new ConcurrentDictionary<string, ConcurrentDictionary<string, byte>>();
  98.         private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, byte>> _reverseMapping =
  99.             new ConcurrentDictionary<string, ConcurrentDictionary<string, byte>>();
  100.  
  101.         public void Add(string key, string value)
  102.         {
  103.             while (true)
  104.             {
  105.                 if (!_straightMapping.TryGetValue(key, out var values))
  106.                 {
  107.                     values = new ConcurrentDictionary<string, byte>();
  108.                     if (!_straightMapping.TryAdd(key, values))
  109.                     {
  110.                         continue;
  111.                     }
  112.                 }
  113.  
  114.                 values.TryAdd(value, 0);
  115.                 ReverseAdd(value, key);
  116.                 break;
  117.             }
  118.         }
  119.  
  120.         private void ReverseAdd(string key, string value)
  121.         {
  122.             while (true)
  123.             {
  124.                 if (!_reverseMapping.TryGetValue(key, out var values))
  125.                 {
  126.                     values = new ConcurrentDictionary<string, byte>();
  127.                     if (!_reverseMapping.TryAdd(key, values))
  128.                     {
  129.                         continue;
  130.                     }
  131.                 }
  132.                 values.TryAdd(value, 0);
  133.                 break;
  134.             }
  135.         }
  136.  
  137.         public bool TryRemove(string map, out ConcurrentDictionary<string, byte> keys)
  138.         {
  139.             if (!_straightMapping.TryRemove(map, out keys)) return false;
  140.            
  141.             foreach (var key in keys)
  142.             {
  143.                 if (!_reverseMapping.TryRemove(key.Key, out var reverseMaps)) continue;
  144.              
  145.                 foreach (var reverseMap in reverseMaps)
  146.                 {
  147.                     if (reverseMap.Key == map ||
  148.                         !_straightMapping.TryGetValue(reverseMap.Key, out var straightMap)) continue;
  149.                
  150.                     straightMap.TryRemove(key.Key, out _);
  151.                     if(straightMap.Count == 0) _straightMapping.TryRemove(reverseMap.Key, out _);
  152.                 }
  153.             }
  154.             return true;
  155.         }
  156.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement