在項目中,我想使用緩存來存儲哈希之類的東西。但是,緩存中存儲的值會不時更改為密鑰。通常從密鑰中選取大約 4 個字符:<- Set hash::helloworldtest = abcdef0123456789-> Get hash::helloworldtest = testef0123456789這大致是我的緩存的結構:type node struct { expires nodeExpiration value interface{}}// ...func (c *Cache) Set(key string, value interface{}, expiration time.Duration) { c.mu.Lock() c.val[key] = &node{ expires: c.expiration(expiration), value: value, } // fmt.Println( ... ) c.mu.Unlock()}func (c *Cache) Get(key string) (interface{}, bool) { c.mu.Lock() if v, o := c.val[key]; o && v != nil { if !v.expires.IsExpired() { // fmt.Println( ... ) c.mu.Unlock() return v.value, true } } c.mu.Unlock() return nil, false}// Cache Backendfunc (b *CacheBackend) GetHash(key string) (res string, err error) { return b.get("hash::" + key)}func (b *CacheBackend) get(key string) (res string, err error) { if v, ok := b.cache.Get(key); ok { if s, ok := v.(string); ok { return s, nil } return "", b.errCast } return "", nil}// go-fiber Routefunc (s *WebServer) handleGetHashAnywhere(ctx *fiber.Ctx) (err error) { path := ctx.Params("anywhere") var res string if res, err = s.Backend.GetHash(path); err != nil { return } if res == "" { ctx.Status(404) } else { ctx.Status(200) } return ctx.SendString(res)}我以前使用過 a,但用 一個 替換了它,認為這可能是問題所在。但與.sync.RWMutexsync.Mutexsync.MutexGet 和 Set 方法在 goroutine 中由 go-fiber 調用,然后返回這些值。有沒有人知道這樣的事情是如何發生的?編輯1:保存而不是工作正常。[]bytestring
1 回答

慕俠2389804
TA貢獻1719條經驗 獲得超6個贊
該問題在零分配下的文檔中進行了描述。摘錄:
由于纖程針對高性能進行了優化,因此從纖程返回的值。默認情況下,Ctx 不是不可變的,并且將在請求之間重復使用。[...]一旦您從處理程序返回,您從上下文中獲得的任何值都將在將來的請求中重復使用,并將在您的腳下更改。
因此,必須復制上下文值,或者必須在纖程配置中傳遞“不可變”標志。
第一種解決方案:
從讀取值中新建緩沖區并復制其內容
buf := bytes.NewBufferString(ctx.Params("hash")) hash := string(buf.Bytes())
第二種解決方案:
使用此處描述的內置函數。utils#CopyString(string)
hash := utils.CopyString(ctx.Params("hash"))
第三個解決方案:
不可變的配置標志
cfg := &fiber.Config{Immutable: true}
然后一切正常。
- 1 回答
- 0 關注
- 99 瀏覽
添加回答
舉報
0/150
提交
取消