Merge pull request #631 from trheyi/main

refactor: Update Request struct to include data caching functionality
This commit is contained in:
Max 2024-06-27 21:12:22 +08:00 committed by GitHub
commit 34db76409e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 80 additions and 12 deletions

View file

@ -107,6 +107,7 @@ func (r *Request) Render() (string, int, error) {
configText := ""
cacheStore := ""
cacheTime := 0
dateCacheTime := 0
configSel := doc.Find("script[name=config]")
if configSel != nil && configSel.Length() > 0 {
@ -132,6 +133,7 @@ func (r *Request) Render() (string, int, error) {
// Cache store
cacheStore = conf.CacheStore
cacheTime = conf.Cache
dateCacheTime = conf.DataCache
}
dataText := ""
@ -163,6 +165,7 @@ func (r *Request) Render() (string, int, error) {
Config: configText,
CacheStore: cacheStore,
CacheTime: time.Duration(cacheTime) * time.Second,
DataCacheTime: time.Duration(dateCacheTime) * time.Second,
}
go core.SetCache(r.File, c)
go log.Trace("[SUI] The page %s is cached file=%s", r.Request.URL.Path, r.File)
@ -174,28 +177,49 @@ func (r *Request) Render() (string, int, error) {
return "", code, err
}
data := r.Request.NewData()
if c.Data != "" {
err = r.Request.ExecStringMerge(data, c.Data)
if err != nil {
return "", 500, fmt.Errorf("data error, please re-complie the page %s", err.Error())
requestHash := r.Hash()
data := core.Data{}
dataCacheKey := fmt.Sprintf("data:%s", requestHash)
dataHitCache := false
// Read from data cache directly
if !r.Request.DisableCache() && c.DataCacheTime > 0 && c.CacheStore != "" {
data, dataHitCache = c.GetData(dataCacheKey)
if dataHitCache {
log.Trace("[SUI] The page %s data is cached %v file=%s key=%s", r.Request.URL.Path, c.DataCacheTime, r.File, dataCacheKey)
}
}
if c.Global != "" {
global, err := r.Request.ExecString(c.Global)
if err != nil {
return "", 500, fmt.Errorf("global data error, please re-complie the page %s", err.Error())
if !dataHitCache {
// Request the data
data = r.Request.NewData()
if c.Data != "" {
err = r.Request.ExecStringMerge(data, c.Data)
if err != nil {
return "", 500, fmt.Errorf("data error, please re-complie the page %s", err.Error())
}
}
if c.Global != "" {
global, err := r.Request.ExecString(c.Global)
if err != nil {
return "", 500, fmt.Errorf("global data error, please re-complie the page %s", err.Error())
}
data["$global"] = global
}
// Save to The Cache
if c.DataCacheTime > 0 && c.CacheStore != "" {
go c.SetData(dataCacheKey, data, c.DataCacheTime)
}
data["$global"] = global
}
// Read from cache directly
key := fmt.Sprintf("page:%s:%s", r.Hash(), data.Hash())
key := fmt.Sprintf("page:%s:%s", requestHash, data.Hash())
if !r.Request.DisableCache() && c.CacheTime > 0 && c.CacheStore != "" {
html, exists := c.GetHTML(key)
if exists {
log.Trace("[SUI] The page %s is cached %v file=%s", r.Request.URL.Path, c.CacheTime, r.File)
log.Trace("[SUI] The page %s is cached %v file=%s key=%s", r.Request.URL.Path, c.CacheTime, r.File, key)
return html, 200, nil
}
}

View file

@ -3,6 +3,7 @@ package core
import (
"time"
jsoniter "github.com/json-iterator/go"
"github.com/yaoapp/gou/store"
"github.com/yaoapp/kun/log"
)
@ -17,6 +18,7 @@ type Cache struct {
HTML string
CacheStore string
CacheTime time.Duration
DataCacheTime time.Duration
}
const (
@ -92,6 +94,46 @@ func (c *Cache) GetHTML(hash string) (string, bool) {
return v.(string), true
}
// GetData get the data
func (c *Cache) GetData(hash string) (Data, bool) {
store, has := store.Pools[c.CacheStore]
if !has {
log.Warn(`[SUI] The cache store "%s" is not found`, c.CacheStore)
return Data{}, false
}
v, has := store.Get(hash)
if !has {
return Data{}, false
}
data := Data{}
err := jsoniter.Unmarshal(v.([]byte), &data)
if err != nil {
log.Error(`[SUI] The data is not a valid json: %s`, err.Error())
return Data{}, false
}
return data, true
}
// SetData set the data
func (c *Cache) SetData(hash string, data Data, ttl time.Duration) {
store, has := store.Pools[c.CacheStore]
if !has {
log.Warn(`[SUI] The cache store "%s" is not found`, c.CacheStore)
return
}
raw, err := jsoniter.Marshal(data)
if err != nil {
log.Error(`[SUI] The data is not a valid json: %s`, err.Error())
return
}
store.Set(hash, raw, ttl)
}
// SetHTML set the html
func (c *Cache) SetHTML(hash, html string, ttl time.Duration) {
store, has := store.Pools[c.CacheStore]

View file

@ -68,6 +68,7 @@ func (page *Page) ExportConfig() string {
"guard": page.Config.Guard,
"cache_store": page.CacheStore,
"cache": page.Config.Cache,
"data_cache": page.Config.DataCache,
})
if err != nil {

View file

@ -298,6 +298,7 @@ type PageSetting struct {
Guard string `json:"guard,omitempty"`
CacheStore string `json:"cache_store,omitempty"`
Cache int `json:"cache,omitempty"`
DataCache int `json:"data_cache,omitempty"`
Description string `json:"description,omitempty"`
SEO *PageSEO `json:"seo,omitempty"`
}