How do I iterate across all sessions in ServiceStack?

为君一笑 提交于 2019-12-06 15:53:19

Using ICacheClientExtended API's

The ICacheClientExtended interface now supports a GetKeysByPattern API that lets you scan for matching keys on Cache Clients that implement the interface. Currently this is implemented by:

  • MemoryCacheClient
  • OrmLiteCacheClient
  • Redis
  • AWS DynamoDbCacheClient

This API now enables the new GetAllKeys() and GetKeysStartingWith() extension methods now available on ICacheClient to scan all cache keys.

var prefix = IdUtils.CreateUrn<IAuthSession>(""); //= urn:iauthsession:
var sessionKeys = Cache.GetKeysStartingWith(sessionPattern).ToList();
var userSessions = Cache.GetValues<AuthUserSession>(sessionKeys);
var existingSessions = userSessions.Values.Where(x => x != null).ToList();

Where existingSessions will contain list of active User Sessions.

Performance will be determined by how many active sessions you have which could be high depending on popularity of your site. Instead of searching all keys you may want to keep a set of session ids per company that you would look through instead by adding them to a collection in a Session or Auth Event.

This new API is available from v4.0.45+ of ServiceStack that's now available on MyGet.

The latest DynamoDbCacheClient is now in the new ServiceStack.Aws NuGet package on MyGet which references the latest v3.* packages from the AWS SDK.


Searching the underlying Caching Provider

Another option is access them directly from your ICacheClient Caching provider if it supports full scans, e.g. if you're using OrmLiteCacheClient to store sessions in an RDBMS you can access all Cache Entries with:

var sessionEntries = Db.Select<CacheEntry>(q => 
    q.Where(x => x.Id.StartsWith("urn:iauthsession:")));
var userSessions = sessionEntries.Map(x => 
    Db.Deserialize<AuthUserSession>(x.Data));

If you're using Redis for Caching you can get it with:

var sessionKeys = Redis.SearchKeys("urn:iauthsession:*");
var sessions = Redis.GetValues<AuthUserSession>(sessionKeys);

Another option would be to maintain a list of all Session Ids for each Company as each user logs in by registering a custom Session or Auth Event which you could maintain in a Redis SET or RDBMS table. In the same registration hook you can verify how many active Sessions they have by using ICacheClient.GetAll API and passing in the session keys for that company, something like:

var sessions = Cache.GetAll<AuthUserSession>(companySessionKeys);
var activeSessions = sessions.Values.Where(x => x != null).ToList();

A little speed check:

I am using InMemoryAuthRepository, and if I have 1000 sessions in cache, and I fetch them, it takes 21 ms. The fetching starts at 4 ms (for 1 session) and goes up to 21 ms for a 1000.

sw.Restart();
IDictionary<string, IAuthSession> sessionList = cacheClient?.GetAll<IAuthSession>(cacheClient?.GetAllKeys());
sw.Stop();
totalMs += sw.ElapsedMilliseconds;
counter2speed.Add(counter, totalMs);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!