Cara menggunakan konteks dalam Pergi untuk melaksanakan penyegaran automatik cache hasil permintaan
Abstrak:
Dalam pembangunan aplikasi web, untuk meningkatkan pengalaman pengguna, kadangkala kita perlu cache hasil beberapa permintaan untuk mengurangkan akses kepada pangkalan data atau lain-lain perkhidmatan. Walau bagaimanapun, tempoh sah data cache adalah masalah Cache tamat tempoh boleh menyebabkan pengguna mendapatkan data tamat tempoh, mengakibatkan paparan dan operasi yang salah. Dalam artikel ini, kami akan meneroka cara menggunakan pakej konteks Go untuk melaksanakan fungsi muat semula automatik cache hasil permintaan untuk memastikan ketepatan masa data cache.
type CacheItem struct { result interface{} expireAt time.Time } type Cache struct { cacheMap map[string]CacheItem mutex sync.RWMutex }
func (c *Cache) Get(key string) interface{} { c.mutex.RLock() defer c.mutex.RUnlock() item, ok := c.cacheMap[key] if ok && item.expireAt.After(time.Now()) { return item.result } // 发起请求并更新缓存 result := makeRequest(key) c.cacheMap[key] = CacheItem{result: result, expireAt: time.Now().Add(time.Minute)} return result }
func (c *Cache) RefreshCache(ctx context.Context, key string) { ticker := time.NewTicker(time.Minute) defer ticker.Stop() for { select { case <-ticker.C: result := makeRequest(key) c.mutex.Lock() c.cacheMap[key] = CacheItem{result: result, expireAt: time.Now().Add(time.Minute)} c.mutex.Unlock() case <-ctx.Done(): return } } }
package main import ( "context" "fmt" "net/http" "sync" "time" ) type CacheItem struct { result interface{} expireAt time.Time } type Cache struct { cacheMap map[string]CacheItem mutex sync.RWMutex } func makeRequest(key string) interface{} { // 模拟请求耗时 time.Sleep(time.Second) return fmt.Sprintf("result for %s", key) } func (c *Cache) Get(key string) interface{} { c.mutex.RLock() defer c.mutex.RUnlock() item, ok := c.cacheMap[key] if ok && item.expireAt.After(time.Now()) { return item.result } result := makeRequest(key) c.cacheMap[key] = CacheItem{result: result, expireAt: time.Now().Add(time.Minute)} return result } func (c *Cache) RefreshCache(ctx context.Context, key string) { ticker := time.NewTicker(time.Minute) defer ticker.Stop() for { select { case <-ticker.C: result := makeRequest(key) c.mutex.Lock() c.cacheMap[key] = CacheItem{result: result, expireAt: time.Now().Add(time.Minute)} c.mutex.Unlock() case <-ctx.Done(): return } } } func main() { cache := &Cache{cacheMap: make(map[string]CacheItem)} http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5)) defer cancel() key := r.URL.Path result := cache.Get(key) fmt.Fprintf(w, "%s: %s", key, result) // 启动刷新缓存的协程 go cache.RefreshCache(ctx, key) }) http.ListenAndServe(":8080", nil) }
Artikel ini memperkenalkan cara menggunakan pakej konteks Go untuk melaksanakan fungsi muat semula automatik cache hasil permintaan. Dengan menggunakan struktur cache dan kunci mutex untuk memastikan keselamatan serentak, dan menggunakan ciri pakej konteks untuk menyegarkan semula cache secara kerap, kami hanya boleh cache hasil permintaan dan memastikan ketepatan masa data. Kod sampel di atas hanyalah demonstrasi mudah Penggunaan sebenar mungkin memerlukan pengubahsuaian dan pengoptimuman yang sesuai berdasarkan keperluan khusus.
Atas ialah kandungan terperinci Cara menggunakan konteks dalam Go untuk melaksanakan muat semula automatik cache hasil permintaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!