【问题标题】:Implementing caching or locking in golang?在 golang 中实现缓存或锁定?
【发布时间】:2021-10-08 04:44:32
【问题描述】:

我有一个 api 需要 api_access_token 的用例...我正在考虑缓存令牌并跟踪过期时间或每个请求的锁以处理并发请求,关于如何实施或任何理想方式的任何建议?

apiAccessToken = createAPIAccessToken(ctx, userId)
url := "https://<hostname>/<api>"

c := http.Client{Timeout: time.Duration(5) * time.Second}
myJson := bytes.NewBuffer([]byte(`{"key":"set.table.attr","Custom_Field":"yes"}`))

req, err := http.NewRequest("POST", url, myJson)
if err != nil {
    return
}
req.Header.Add("token", apiAccessToken)
res, err := c.Do(req)
defer res.Body.Close()

【问题讨论】:

  • 如果你有少量的值要本地存储在内存中,你可以检查github.com/patrickmn/go-cache,否则需要寻找像redis这样的外部缓存

标签: go caching locking access-token


【解决方案1】:

也许这样的事情可以让你开始。这会从缓存中返回所有查询,并按照time.Ticker 的计划在后台异步更新缓存

package main

import(
    "fmt"
    "time"
    "sync"
)

type Cache struct {
    data interface{}
    update func(interface{})interface{}
    l sync.Mutex
    wg sync.WaitGroup
    update_period time.Duration
    done chan struct{}
}

func (c *Cache)Get() interface{} {
    c.l.Lock()
    defer c.l.Unlock()
    return c.data
}

func (c *Cache)periodicUpdater() {
        c.wg.Add(1)
        defer c.wg.Done()
        t := time.NewTicker(c.update_period)
        for {
            select{
                case <-t.C:
                    fmt.Println("Updating")
                    newdata := c.update(c.data)
                    c.l.Lock()
                    c.data = newdata
                    c.l.Unlock()
                case <-c.done:
                    t.Stop()
                    return
            }
        }
}


func main() {
    c := &Cache{
        update: func(data interface{}) interface{} {
            if d, ok := data.(int); !ok {
                panic("unexpected type")
            } else {
                return d+1
            }
        },
        update_period: 1 * time.Second,
        done: make(chan struct{}),
    }
    c.data = c.update(0)
    defer c.wg.Wait()
    go c.periodicUpdater()
    gt := time.NewTicker(773*time.Millisecond)
    for {
        select {
        case <-gt.C:
                x := c.Get()
                fmt.Println(x)
                if i, ok := x.(int); !ok {
                    panic("how was this not an int!?!")
                } else if i > 15 {
                    c.done <- struct{}{}
                    return
                }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 2023-03-05
    • 2016-11-25
    • 2021-10-23
    相关资源
    最近更新 更多