首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >种族(?)地图中的互斥数据

种族(?)地图中的互斥数据
EN

Stack Overflow用户
提问于 2021-04-03 10:29:17
回答 1查看 206关注 0票数 0

在一个项目中,我想使用缓存来存储像散列这样的东西。但是,缓存中存储的值有时会更改为键。通常,键中的大约4个字符将被接管:

代码语言:javascript
复制
<- Set hash::helloworldtest = abcdef0123456789
-> Get hash::helloworldtest = testef0123456789

这大致是我的缓存的结构方式:

代码语言:javascript
复制
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 Backend
func (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 Route
func (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)
}

我以前使用过sync.RWMutex,但是用sync.Mutex代替了它,我认为这可能就是问题所在。但sync.Mutex也是如此。

去纤维在goroutine中调用Get和Set方法,然后返回这些值。

有人知道这种事怎么会发生吗?

编辑1:保存[]byte而不是string很好。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-09 10:57:45

多亏了@majodev,这个问题终于得到了妥善的解决。

零分配下的文档中描述了这个问题。节选:

由于光纤是为高性能而优化的,因此从fiber.Ctx返回的值在默认情况下是而不是不可变的,并且在请求中将被重用。..。一旦您从处理程序返回,您从上下文中获得的任何值将在未来的请求中重新使用,并将在您脚下进行更改。

因此,必须复制上下文值,或者在光纤配置中传递“不可变”标志。

第一解决方案:

读取值中的新缓冲区并复制其内容

代码语言:javascript
复制
buf := bytes.NewBufferString(ctx.Params("hash"))
hash := string(buf.Bytes())

第二解决方案:

使用内置函数utils#CopyString(string)描述这里

代码语言:javascript
复制
hash := utils.CopyString(ctx.Params("hash"))

第三种解决方案:

不变配置标志

代码语言:javascript
复制
cfg := &fiber.Config{Immutable: true}

那么一切都正常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66930097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档