json - API 库中的后台获取

标签 json rest go

我正在编写一个 API 客户端(库),它命中一个 JSON 端点并填充一个内存缓存。

到目前为止:

  • 我在库的 init() 函数中启动了一个 time.Ticker 循环,它每分钟都会访问 API,从而刷新缓存(一个嵌入 JSON 结构和时间戳的结构)。
  • 库中面向公众的函数调用只是从 catch 中获取,因此不需要担心自己的速率限制,但如果他们想确认数据的新鲜度,可以检查时间戳<

但是,在 init() 中启动 time.Ticker 感觉不太对:我还没有看到任何其他库这样做。然而,我确实希望避免包用户不得不做大量的工作只是为了从几个 JSON 端点取回数据。

我的公共(public) API 如下所示:

// Example usage:
// rt := api.NewRT()
// err := rt.GetLatest
// tmpl.ExecuteTemplate(w, "my_page.tmpl", M{"results": rt.Data})

func (rt *RealTime) GetLatest() error {
    rt = realtimeCache.Cached
    if rt == nil {
        return errors.New("No cached response is available.")
    }

    return nil
}

内部 getter 如下:

func fetchLatest() error {
    log.Println("Fetching latest RT results.")
    resp, err := http.Get(realtimeEndpoint)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return err
    }

    // Lock our cache from writes
    realtimeCache.Lock()
    defer realtimeCache.Unlock()

    var rt *RealTime
    err = json.Unmarshal(body, &rt)
    if err != nil {
        return err
    }

    // Update the cache
    realtimeCache.Cached = rt

    return nil
}

func init() {
    // Populate the cache on start-up
    fetchLatest()
    fetchHistorical()

    // Refresh the cache every minute (default)
    ticker := time.NewTicker(time.Second * interval)
    go func() {
        for _ = range ticker.C {
            fetchLatest()
            fetchHistorical()
        }
    }()
}

API 的其他部分也有类似的功能(我正在模块化,但我一开始就保持简单),但这就是它的要点。

有没有更好的方法让后台 worker 获取仍然对用户友好的结果?

最佳答案

恕我直言,在 init() 函数上启动计时器是个坏主意,原因很简单,您的 API 的用户应该决定是否以及何时进行抓取/缓存/更新。

我建议使用 NewRT() 函数中的选项或包范围的 bool 值(api.AutoUpdate, api.Caching).

根据访问者的要求,您可以采取适当的行动:

  • 如果未启用缓存,则检索数据
  • 如果启用了缓存但未启用自动更新,则检查数据的新鲜度,并在需要时刷新
  • 如果启用了缓存和自动更新,则什么都不做,因为您的计时器(在 NewRT() 函数中启动)将为您处理数据

这样您就不会在用户需要之前开始检索任何内容,而是可以灵活地让您的用户决定他们是否需要额外的功能。

请注意,您应该确保在删除相应的结构后不会保留不必要的计时器。

关于json - API 库中的后台获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24375671/

相关文章:

go - golang插件如何验证包的版本?

java - 尝试从 android studio 中的资源加载 json

c++ - 用于嵌入式平台的 C++ 中的简单 JSON-RPC?

node.js - 如何保护开放的 REST API 免受 Node.js 中的滥用?

Spring MVC @RestController 和重定向

search - 如何通过基本名称(不带扩展名)检查文件是否存在?

http - 为什么在使用 Go HTTP 客户端时我的 HTTP POST 请求会有 60 秒的延迟?

asp.net - Javascript JSON.stringify 对象包含数组序列化问题

javascript - jquery中如何将json输出转换为数组

node.js - LoopBack 过滤器 "where and "在任何值中返回错误/相同结果