在handlerfunc中将元素添加到切片中,并作为整体返回。

huangapple go评论91阅读模式
英文:

Adding element to slice in handlerfunc and return as a whole

问题

我正在编写一个用于学习Go的服务。下面是我的主要函数。它首先读取一个XML文件并将其存储在一个切片中。我有一个/rss端点,用于从存储在“数据库”中的项目中输出RSS源。这部分工作正常。我还有一个端点(/add/{base64}),用于向该切片中添加新项目。不幸的是,我不知道该如何做到这一点。由于某种原因,我需要返回添加了记录的新的database,以便它可以在/rss端点中使用。但是如何实现呢?

我的具体问题是:

  1. 我知道如何向database添加记录。
  2. 但是我不知道如何返回完整的(包括添加的)数据库,以便/rss端点能够使用它。所以我希望让rest.AddArticle返回新的数据库,这样/rss端点就知道添加的项目了。
func main() {
    defer glog.Flush()

    // 读取数据库
    database := model.ReadFileIntoSlice()

    // 初始化mux路由器
    r := mux.NewRouter()

    // HTTP处理函数
    r.HandleFunc("/add/{base64url}", rest.AddArticle(database))
    r.HandleFunc("/rss", rest.GenerateRSS(database))

    // 启动服务器
    http.Handle("/", r)
    glog.Infof("运行在端口 %d", *port)
    http.ListenAndServe(":"+strconv.Itoa(*port), nil)
}

或者是否有其他解决方案可以完成这个任务?我只是希望database在所有包中都可用。

英文:

I'm writing a service to learn Go. My main function can be found below. It starts with reading an XML file and storing them in a slice. I have a /rss endpoint which outputs a RSS feed from the items stored in the "database". This is working fine. I also have an endpoint (/add/{base64}) which is used to add a new item to that slice. Unfortunately I don't know how to do this. For some reason I need to return the new database with the added record, so it gets available to the /rss. But how?

My concrete problem is:

  1. I know how to add a record to database

  2. But I don't know how to return the full (including the added) database so the /rss endpoint is able to use it. So I want to let the rest.AddArticle return the new database so the /rss endpoint knows the added item.

    func main() {
    defer glog.Flush()
    
    // read database
    database := model.ReadFileIntoSlice()
    
    // initialise mux router
    r := mux.NewRouter()
    
    // http handles
    r.HandleFunc("/add/{base64url}", rest.AddArticle(database))
    r.HandleFunc("/rss", rest.GenerateRSS(database))
    
    // start server
    http.Handle("/", r)
    glog.Infof("running on port %d", *port)
    http.ListenAndServe(":"+strconv.Itoa(*port), nil)
    }
    

Or is there some other solution which does the job? I just want database to be available through all packages.

答案1

得分: 1

从我所了解的情况来看,问题在于你正在向数据库写入数据,但是从缓存版本中读取数据,因此 rss 的响应并不反映请求时的模型状态。如果你看一下这段代码:

database := model.ReadFileIntoSlice()

// 初始化 mux 路由器
r := mux.NewRouter()

// 处理 HTTP 请求
r.HandleFunc("/add/{base64url}", rest.AddArticle(database))

你需要修改 database 的值。有很多方法可以做到这一点。几个选项包括:1)在某个对象或包级别上定义它,然后直接从 AddArticle 方法所在的位置修改它;2)刷新内存中的版本,在返回结果之前再次从数据库中读取,以确保获取到最新的数据(当然会有性能影响);3)不要按值传递 database,而是将参数改为指针。AddArticle 方法得到的是 database 的副本,而不是你在 rss 调用中读取的版本的地址。你可以将一个指针传递给该方法,以便修改原始副本(这样做在模型变得更大时性能也更好)。

根据你的程序的简单性,我可能会选择第三种方法。实际上,第二种方法是更健壮的解决方案,对于严肃的企业软件来说,可能需要更接近这种方式(如果你的应用程序是负载均衡的,那么你的模型可能无法正常工作)。

英文:

From what I can tell the problem is that you're writing to your db but you're reading from the cached version so the response of rss just doesn't reflect the model at the time the request is made. If you look at this code;

database := model.ReadFileIntoSlice()

// initialise mux router
r := mux.NewRouter()

// http handles
r.HandleFunc("/add/{base64url}", rest.AddArticle(database))

you somehow need to modify the value of database. There are many ways you could do this. A few options would be 1) define it on some object or at a package level and then directly modify it from wherever AddArticle is defined. 2) refresh your in memory version, ie before you return the results, read from the db again so you're assured to have the latest (obv performance implications) 3) don't pass database by value, make the argument a pointer instead. AddArticle is getting a copy of database rather than the address to the version you're reading from in your rss call. You could instead pass a pointer into that method so that the original copy is modified (it also performs substantially better as your model gets larger).

Based on the simplicity of your program I'd probably do 3. Realistically 2 is a more robust solution and serious enterprise software probably would require something more along those lines (your model doesn't work if your app is load balanced or something like that).

huangapple
  • 本文由 发表于 2015年5月5日 02:39:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/30037515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定