种族(?) 与互斥体 - 地图中的数据损坏

在项目中,我想使用缓存来存储哈希之类的东西。但是,缓存中存储的值会不时更改为密钥。通常从密钥中选取大约 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 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)

}

我以前使用过 a,但用 一个 替换了它,认为这可能是问题所在。但与.sync.RWMutexsync.Mutexsync.Mutex


Get 和 Set 方法在 goroutine 中由 go-fiber 调用,然后返回这些值。


有没有人知道这样的事情是如何发生的?


编辑1:保存而不是工作正常。[]bytestring

桃花长相依
浏览 84回答 1
1回答

慕侠2389804

该问题在零分配下的文档中进行了描述。摘录:由于纤程针对高性能进行了优化,因此从纤程返回的值。默认情况下,Ctx&nbsp;不是不可变的,并且将在请求之间重复使用。[...]一旦您从处理程序返回,您从上下文中获得的任何值都将在将来的请求中重复使用,并将在您的脚下更改。因此,必须复制上下文值,或者必须在纤程配置中传递“不可变”标志。第一种解决方案:从读取值中新建缓冲区并复制其内容buf&nbsp;:=&nbsp;bytes.NewBufferString(ctx.Params("hash")) hash&nbsp;:=&nbsp;string(buf.Bytes())第二种解决方案:使用此处描述的内置函数。utils#CopyString(string)hash&nbsp;:=&nbsp;utils.CopyString(ctx.Params("hash"))第三个解决方案:不可变的配置标志cfg&nbsp;:=&nbsp;&fiber.Config{Immutable:&nbsp;true}然后一切正常。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go