Reputation: 520
I'm just starting to read about ServiceStack's session and caching mechanisms so I could be missing something. Is there a way to use multiple ICacheClient implementations with ServiceStack?
According to https://github.com/ServiceStack/ServiceStack/wiki/Sessions and https://github.com/ServiceStack/ServiceStack/wiki/Caching you can add a session Plugin as follows:
public override void Configure(Container container)
{
Plugins.Add(new SessionFeature());
}
And you can register a particular ICacheClient implementation like so:
container.Register<ICacheClient>(new MemoryCacheClient());
What I'm thinking is that you might have cases where you need a stateful service that would maintain a great deal of session state for maximum performance, but for more typical caching requirements, you'd want to use something like Redis:
container.Register<IRedisClientsManager>(c =>
new PooledRedisClientManager("localhost:6379"));
container.Register<ICacheClient>(c =>
(ICacheClient)c.Resolve<IRedisClientsManager>().GetCacheClient());
But is there a way to switch between these? Would you have to create a provider manually (bypassing IoC) and use it for either the in-memory or the Redis caching (using IoC for the other ICacheClient instance)? Or create a wrapper around both ICacheClient implementations and use something like a special key naming pattern to internally switch between using the in-memory vs. Redis cache?
Also, how would you deal with accessing data via ISession? Could you potentially back the ISession with the in-memory ICacheClient while using the Redis one just when you directly refer to your auto-wired ICacheClient property?
Upvotes: 2
Views: 1776
Reputation: 827
Servicestack session state is maintained using the ICacheClient. You would need to decide which provider you want servicestack to use for caching and set this as you've described - ie Memcached:
container.Register<ICacheClient>(new MemoryCacheClient());
If you wanted to use another type of caching register it in the IOC, giving:
container.Register<ICacheClient>(new MemoryCacheClient()); // For servicestack session state
//REDIS for other caching options
container.Register<IRedisClientsManager>(c => new PooledRedisClientManager("localhost:6379"));
container.Register<IREDISClient>(c => (IREDISClient)c.Resolve<IRedisClientsManager>().GetClient());
Your different classes would then use the caching provider that is most appropriate by defining the Caching interface that it requires:
public ICacheClient Cache { get; set; }
or
public IREDISClient REDISCache { get; set; }
You could make both available in your services by extending the servicestack service class and creating your own appservicebase as demonstrate in the socialbootstrap project. You could then make both cache models available.
I use REDIS for all caching, it's quick enough for my needs and in a multi-server architecture allows servers to be taken down for maintenance without any loss of user sessions.
I do still have two cache providers through, the standard REDIS Client - wired up to ICacheClient - and the native REDIS client - wired up to IRedisNativeClient. This is due to the serialisation employed by the standard REDIS client not working with some non-POCO objects that I need to temporarily persist.
Upvotes: 3