diff --git a/cache/ICache.go b/cache/ICache.go index 3d9c9be..3b1da7f 100644 --- a/cache/ICache.go +++ b/cache/ICache.go @@ -51,4 +51,16 @@ type ICache interface { // // Date : 16:46 2024/6/3 SetValue(cacheKey string, cacheValue string) error + // TTL 缓存剩余生命周期(单位: s) + // + // Author : go_developer@163.com<白茶清欢> + // + // Date : 18:39 2024/10/9 + TTL(cacheKey string) int64 + // PreHeatConfig 缓存预热配置 + // + // Author : go_developer@163.com<白茶清欢> + // + // Date : 18:42 2024/10/9 + PreHeatConfig() *define.CachePreHeatConfig } diff --git a/client.go b/client.go index 0ad8101..611271c 100644 --- a/client.go +++ b/client.go @@ -148,9 +148,54 @@ func (hc *HttpClient) Request() *define.Response { ) if cacheResult = hc.getCacheResult(); nil != cacheResult { - return cacheResult + // 判断是否开启预热 + inputCachePreHeatConfig := hc.cacheInstance.PreHeatConfig() + var cachePreHeatConfig define.CachePreHeatConfig + serialize.JSON.TransitionIgnoreError(inputCachePreHeatConfig, &cachePreHeatConfig) + if !cachePreHeatConfig.Enable || (cachePreHeatConfig.MinTTL <= 0 && cachePreHeatConfig.MinPercent <= 0 && !cachePreHeatConfig.Force) { + // 无预热配置或未启用预热或者未设置预热规则 + return cacheResult + } + go func() { + // 判断是否触发预热 + if cachePreHeatConfig.Force { + _ = hc.requestBackendApi() + return + } + // 将百分比的配置归一化成最小剩余时间的配置 + if cachePreHeatConfig.MinPercent > 0 { + expectMinTTL := hc.cacheInstance.CacheTime() * cachePreHeatConfig.MinPercent / 100 + if cachePreHeatConfig.MinTTL == 0 || cachePreHeatConfig.MinTTL > expectMinTTL { + cachePreHeatConfig.MinTTL = expectMinTTL + } + } + if cachePreHeatConfig.MinTTL <= 0 { + // 未配置最小剩余时间 + return + } + ttl := hc.cacheInstance.TTL(cacheResult.CacheInfo.CacheKey) + if ttl < 0 { + // 不存在或者未设置有效期 + return + } + + if ttl <= cachePreHeatConfig.MinTTL { + // 配置了最小剩余时间,并且key剩余有效期小于最小剩余时间 + _ = hc.requestBackendApi() + } + }() } + return hc.requestBackendApi() + +} + +// requestBackendApi 请求后端接口 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:47 2024/10/9 +func (hc *HttpClient) requestBackendApi() *define.Response { hc.Client.OnBeforeRequest(hc.getRequestValidateMiddleware()) // 请求参数验证中间件必注册 hc.Client.OnAfterResponse(hc.getResponseValidateMiddleware()) // 响应验证中间件必注册 var ( diff --git a/define/cache.go b/define/cache.go new file mode 100644 index 0000000..24c74a3 --- /dev/null +++ b/define/cache.go @@ -0,0 +1,20 @@ +// Package define ... +// +// Description : define ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-10-09 18:39 +package define + +// CachePreHeatConfig 缓存预热配置, MinPercent / MinTTL 同时配置, 则任意一个满足, 均进行预热 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:40 2024/10/9 +type CachePreHeatConfig struct { + Enable bool `json:"enable"` // 缓存预热是否可用 + MinPercent int64 `json:"min_percent"` // 最小百分比, 剩余有效期低于此百分比进行预热 + MinTTL int64 `json:"min_ttl"` // 最小剩余生命周期, 低于此百分比进行预热 + Force bool `json:"force"` // 启用预热的情况下, 强制预热, 会忽略 MinPercent / MinTTL 的配置 +}