| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- 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<TkEndpointConfigDTO> _cached;
- // 添加到 TkEndpointCore 类中
- private static readonly ConcurrentDictionary<int, List<TkEndpointConfigDTO>> _accountEndpointCache = new();
- private static async Task<IEnumerable<TkEndpointConfigDTO>> ListAsync(bool force = false)
- {
- // 内存缓存检查
- if (!force && _cached != null) return _cached;
- string cache_key = "cache:tk_endpoint_config";
- if (!force)
- {
- var cachedList = await RedisHelper.GetAsync<IEnumerable<TkEndpointConfigDTO>>(cache_key);
- if (cachedList != null)
- {
- _cached = cachedList;
- return cachedList;
- }
- }
- // 获取新数据
- await _semaphore.WaitAsync();
- try
- {
- // 双重检查,防止并发情况下重复加载
- if (!force)
- {
- var cachedList = await RedisHelper.GetAsync<IEnumerable<TkEndpointConfigDTO>>(cache_key);
- if (cachedList != null)
- {
- _cached = cachedList;
- return cachedList;
- }
- }
- // 从数据库加载数据
- var list = new DBContext.Table("tk_endpoint_config")
- .Where("status=@status", new { status = 1 })
- .Select<TkEndpointConfigDTO>();
- 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<List<TkEndpointConfigDTO>> 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();
- }
- }
|