1- using Microsoft . AspNetCore . Http ;
2- using Microsoft . Extensions . Caching . Distributed ;
3- using Microsoft . Extensions . Caching . StackExchangeRedis ;
1+ using System ;
42using System . Collections . Concurrent ;
5- using System . Threading . Tasks ;
3+ using System . Linq ;
64using System . Threading ;
7- using System ;
5+ using System . Threading . Tasks ;
86using GeneXus . Services ;
9- using System . Linq ;
7+ using Microsoft . AspNetCore . Http ;
8+ using Microsoft . Extensions . Caching . Distributed ;
9+ using Microsoft . Extensions . Caching . StackExchangeRedis ;
1010
1111namespace GeneXus . Application
1212{
1313 public class TenantRedisCache : IDistributedCache
1414 {
15+ private static readonly IGXLogger log = GXLoggerFactory . GetLogger < TenantRedisCache > ( ) ;
16+
1517 private readonly IHttpContextAccessor _httpContextAccessor ;
1618 private readonly IServiceProvider _serviceProvider ;
1719 private readonly ConcurrentDictionary < string , RedisCache > _redisCaches = new ( ) ;
@@ -25,32 +27,85 @@ public TenantRedisCache(IHttpContextAccessor httpContextAccessor, IServiceProvid
2527 private IDistributedCache GetTenantCache ( )
2628 {
2729 string tenantId = _httpContextAccessor . HttpContext ? . Items [ TenantMiddleware . TENANT_ID ] ? . ToString ( ) ?? "default" ;
28-
29- return _redisCaches . GetOrAdd ( tenantId , id =>
30+ RedisCache cache ;
31+ bool existed = _redisCaches . TryGetValue ( tenantId , out cache ) ;
32+ if ( existed )
33+ {
34+ log . LogDebug ( $ "GetTenantCache: tenantId={ tenantId } , cache reused") ;
35+ return cache ;
36+ }
37+ else
3038 {
31- ISessionService sessionService = GXSessionServiceFactory . GetProvider ( ) ;
32- var options = new RedisCacheOptions
39+ log . LogDebug ( $ "GetTenantCache: tenantId= { tenantId } , cache created" ) ;
40+ cache = _redisCaches . GetOrAdd ( tenantId , id =>
3341 {
34- Configuration = sessionService . ConnectionString ,
35- InstanceName = $ "{ id } :"
36- } ;
37- return new RedisCache ( options ) ;
38- } ) ;
42+ ISessionService sessionService = GXSessionServiceFactory . GetProvider ( ) ;
43+ var options = new RedisCacheOptions
44+ {
45+ Configuration = sessionService . ConnectionString ,
46+ InstanceName = $ "{ id } :"
47+ } ;
48+ return new RedisCache ( options ) ;
49+ } ) ;
50+ }
51+ return cache ;
52+ }
53+ public byte [ ] Get ( string key )
54+ {
55+ IDistributedCache cache = GetTenantCache ( ) ;
56+ log . LogDebug ( $ "CacheGet: key={ key } ") ;
57+ return cache . Get ( key ) ;
58+ }
59+ public Task < byte [ ] > GetAsync ( string key , CancellationToken token = default )
60+ {
61+ IDistributedCache cache = GetTenantCache ( ) ;
62+ log . LogDebug ( $ "CacheGetAsync: key={ key } ") ;
63+ return cache . GetAsync ( key , token ) ;
64+ }
65+ public void Refresh ( string key )
66+ {
67+ IDistributedCache cache = GetTenantCache ( ) ;
68+ log . LogDebug ( $ "CacheRefresh: key={ key } ") ;
69+ cache . Refresh ( key ) ;
70+ }
71+ public Task RefreshAsync ( string key , CancellationToken token = default )
72+ {
73+ IDistributedCache cache = GetTenantCache ( ) ;
74+ log . LogDebug ( $ "CacheRefreshAsync: key={ key } ") ;
75+ return cache . RefreshAsync ( key , token ) ;
76+ }
77+ public void Remove ( string key )
78+ {
79+ IDistributedCache cache = GetTenantCache ( ) ;
80+ log . LogDebug ( $ "CacheRemove: key={ key } ") ;
81+ cache . Remove ( key ) ;
82+ }
83+ public Task RemoveAsync ( string key , CancellationToken token = default )
84+ {
85+ IDistributedCache cache = GetTenantCache ( ) ;
86+ log . LogDebug ( $ "CacheRemoveAsync: key={ key } ") ;
87+ return cache . RemoveAsync ( key , token ) ;
88+ }
89+ public void Set ( string key , byte [ ] value , DistributedCacheEntryOptions options )
90+ {
91+ string sliding = options ? . SlidingExpiration ? . ToString ( ) ?? "none" ;
92+ IDistributedCache cache = GetTenantCache ( ) ;
93+ log . LogDebug ( $ "CacheSet: key={ key } , slidingExpiration={ sliding } ") ;
94+ cache . Set ( key , value , options ) ;
95+ }
96+ public Task SetAsync ( string key , byte [ ] value , DistributedCacheEntryOptions options , CancellationToken token = default )
97+ {
98+ string sliding = options ? . SlidingExpiration ? . ToString ( ) ?? "none" ;
99+ IDistributedCache cache = GetTenantCache ( ) ;
100+ log . LogDebug ( $ "CacheSetAsync: key={ key } , slidingExpiration={ sliding } ") ;
101+ return cache . SetAsync ( key , value , options , token ) ;
39102 }
40-
41- public byte [ ] Get ( string key ) => GetTenantCache ( ) . Get ( key ) ;
42- public Task < byte [ ] > GetAsync ( string key , CancellationToken token = default ) => GetTenantCache ( ) . GetAsync ( key , token ) ;
43- public void Refresh ( string key ) => GetTenantCache ( ) . Refresh ( key ) ;
44- public Task RefreshAsync ( string key , CancellationToken token = default ) => GetTenantCache ( ) . RefreshAsync ( key , token ) ;
45- public void Remove ( string key ) => GetTenantCache ( ) . Remove ( key ) ;
46- public Task RemoveAsync ( string key , CancellationToken token = default ) => GetTenantCache ( ) . RemoveAsync ( key , token ) ;
47- public void Set ( string key , byte [ ] value , DistributedCacheEntryOptions options ) => GetTenantCache ( ) . Set ( key , value , options ) ;
48- public Task SetAsync ( string key , byte [ ] value , DistributedCacheEntryOptions options , CancellationToken token = default ) => GetTenantCache ( ) . SetAsync ( key , value , options , token ) ;
49103 }
50104
51-
52105 public class TenantMiddleware
53106 {
107+ private static readonly IGXLogger log = GXLoggerFactory . GetLogger < TenantMiddleware > ( ) ;
108+
54109 internal const string TENANT_ID = "TenantId" ;
55110 private readonly RequestDelegate _next ;
56111
@@ -63,8 +118,9 @@ public async Task Invoke(HttpContext context)
63118 {
64119 string host = context . Request . Host . Host ;
65120 string subdomain = host . Split ( '.' ) . FirstOrDefault ( ) ;
66- context . Items [ TENANT_ID ] = subdomain ;
121+ context . Items [ TENANT_ID ] = subdomain ;
67122
123+ log . LogDebug ( $ "TenantMiddleware: host={ host } , subdomain={ subdomain } , path={ context . Request . Path } ") ;
68124 await _next ( context ) ;
69125 }
70126 }
0 commit comments