MichaCo / CacheManager

CacheManager is an open source caching abstraction layer for .NET written in C#. It supports various cache providers and implements many advanced features.
http://cachemanager.michaco.net
Apache License 2.0
2.34k stars 457 forks source link

Problem with Twemproxy integration #262

Closed pablocoacci closed 5 years ago

pablocoacci commented 5 years ago

Hi Michaco,

I reach you because I'm having some problems while using Michaco CacheManager with Twemproxy integration. Everything works fine when using Redis directly but when I try to save the key/value using TwemProxy integration it is never saved and does not throw any exception.

Here I leave a portion of the code where the CacheFactory is created:

CacheFactory.Build<TData>("CacheManager", settings =>
    settings
        .WithUpdateMode(CacheUpdateMode.Up)
        .WithSystemRuntimeCacheHandle(localCacheHandleName)
        .WithExpiration(ExpirationMode.Absolute, _expireConfigDuration)
        .And.WithJsonSerializer()
        .WithRedisConfiguration(redisCacheHandleName, rcb =>
        {
            rcb = rcb
                .WithEndpoint(_redisEndPoint, _redisPortNumber)
                .WithPassword(_redisPassword)
                .WithAllowAdmin()
                .UseTwemproxy()
                .WithDatabase(_redisDataBaseNumber);

            if (_redisIsSsl)
                rcb = rcb.WithSsl();
        })
        .WithLogging(typeof(CacheManagerLoggerFactory), new object[] { })
        .WithRetryTimeout(_redisTimeOutRetries)
        .WithMaxRetries(_redisMaxRetries)
        .WithRedisBackplane(redisCacheHandleName)
        .WithRedisCacheHandle(redisCacheHandleName, true)
    );

This is the code that I'm using to save the key:

var item = _cache.GetOrAdd("mykey", region, (k, r) => new CacheItem<T>(k,r, dataLoadFunc(), ExpirationMode.Absolute, _expiration));

dataLoadFunc() function does a query to a SQL DB.

Thanks!

MichaCo commented 5 years ago

Hard to tell without a repro. Do you have any log information coming from CacheManager. edit: Your configuration looks about right.

If it doesn't throw, it should at least try to store the values and that should be visible in the logs.

Tbh, I don't use a proxy myself so this "fallback" is not tested very well in general.

pablocoacci commented 5 years ago

Hi Michaco. Thanks for the quick reply. This is the exception that is generated when the ChacheManager is created:

ERROR CacheManager.Core.BaseCacheManager`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] [(null)] - EventId: 0, Message: Error occurred while creating the cache manager.
System.InvalidOperationException: Failed to initialize instance of type CacheManager.Redis.RedisCacheBackplane. ---> System.NotSupportedException: The pub/sub API is not available via twemproxy
   en StackExchange.Redis.ConnectionMultiplexer.GetSubscriber(Object asyncState) en c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:línea 1027
   en CacheManager.Redis.RedisConnectionManager.get_Subscriber()
   en CacheManager.Redis.RedisCacheBackplane.Subscribe()
   en CacheManager.Redis.RedisCacheBackplane.<.ctor>b__10_0()
   en CacheManager.Redis.RetryHelper.<>c__DisplayClass3_0.<Retry>b__0()
   en CacheManager.Redis.RetryHelper.Retry[T](Func`1 retryme, Int32 timeOut, Int32 retries, ILogger logger)
   en CacheManager.Redis.RetryHelper.Retry(Action retryme, Int32 timeOut, Int32 retries, ILogger logger)
   en CacheManager.Redis.RedisCacheBackplane..ctor(ICacheManagerConfiguration configuration, ILoggerFactory loggerFactory)

Thanks!

MichaCo commented 5 years ago

Ah well, so you did get an exception and the message clearly explains why its not working. You cannot use the backplane feature with TwemProxy because the proxy doesn't have PubSub. (I forgot about that, otherwise I'd have mentioned that earlier ^^)

pablocoacci commented 5 years ago

Yes, with that in mind, I delete the "WithRedisBackplane()" line from the creations of the CacheManager object but the problem still persists. The exception is not thrown but the key is still not saved y Redis.

Thanks!