using dodohold.core; using molilian.core; using System; using System.Collections.Concurrent; using System.Linq; using YunhuiKit; using static molilian.core.TkPoolCore; public partial class TkEndpointCore { private static SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); private static IEnumerable _cached; // 添加到 TkEndpointCore 类中 private static readonly ConcurrentDictionary> _accountEndpointCache = new(); private static async Task> ListAsync(bool force = false) { // 内存缓存检查 if (!force && _cached != null) return _cached; string cache_key = "cache:tk_endpoint_config"; if (!force) { var cachedList = await RedisHelper.GetAsync>(cache_key); if (cachedList != null) { _cached = cachedList; return cachedList; } } // 获取新数据 await _semaphore.WaitAsync(); try { // 双重检查,防止并发情况下重复加载 if (!force) { var cachedList = await RedisHelper.GetAsync>(cache_key); if (cachedList != null) { _cached = cachedList; return cachedList; } } // 从数据库加载数据 var list = new DBContext.Table("tk_endpoint_config") .Where("status=@status", new { status = 1 }) .Select(); if (list == null) return default; // 更新调用次数 //foreach (var item in list) //{ // item.current_daily_calls = await RiskControlCore.GetAllNodesTkEndpointCallsAsync(item.id, DateTime.Now.ToString("yyyyMMdd")); // item.current_hourly_calls = await RiskControlCore.GetAllNodesTkEndpointCallsAsync(item.id, DateTime.Now.ToString("yyyyMMddHH")); //} // 更新缓存 await RedisHelper.SetAsync(cache_key, list, 30 * 86400); _cached = list; _accountEndpointCache.Clear(); return list; } finally { _semaphore.Release(); } } public static async Task> GetEndpointsByAccountAsync(int accountId) { // 1. 从缓存读取(直接返回副本) if (_accountEndpointCache.TryGetValue(accountId, out var cached)) return cached.Select(x => x.DeepCopy()).ToList(); // 2. 获取所有端点(包含全局和专属) var allEndpoints = (await ListAsync())?.Where(e => e.status).ToList() ?? []; // 3. 合并逻辑:专属配置覆盖全局配置(关键!) var mergedEndpoints = allEndpoints .GroupBy(e => e.endpoint) .Select(g => { // 优先取专属配置 var accountSpecific = g.FirstOrDefault(e => e.tk_pool_id == accountId); if (accountSpecific != null) return accountSpecific.DeepCopy(); // 深拷贝专属配置 // 否则取全局配置(tk_pool_id=0) var global = g.FirstOrDefault(e => e.tk_pool_id == 0); return global?.DeepCopy(); // 深拷贝全局配置 }) .Where(e => e != null) .ToList(); // 4. 存入缓存(存储深拷贝后的组合配置) _accountEndpointCache.TryAdd(accountId, mergedEndpoints.Select(x => x.DeepCopy()).ToList()); return mergedEndpoints; } // 添加缓存清理方法 public static void ClearEndpointCache(int accountId) { _accountEndpointCache.TryRemove(accountId, out _); } public static void Refresh() { _ = AllListAsync(true); _ = ListAsync(true); _accountEndpointCache.Clear(); } }