在项目中,我想使用缓存来存储哈希之类的东西。但是,缓存中存储的值会不时更改为密钥。通常从密钥中选取大约 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 关注
- 83 浏览
添加回答
举报
0/150
提交
取消