我想在 mgo 会话完全流式传输到客户端后关闭它。起初,我认为这可能会起作用,但似乎
defer
只是等待 func 开始返回或其他什么。
func (c App) OpenFile(fileId string) revel.Result {
// convert string to bson.ObjectId
objId := bson.ObjectIdHex(fileId)
file, session := OpenFile(objId)
defer session.Close()
// memfile io.Reader, filename string, delivery ContentDisposition, modtime time.Time
var now = time.Now()
return c.RenderBinary(file, "filename", "inline", now)
}
我不知道你的
OpenFile
函数在做什么,但我假设它使用 Mongo 的 GridFS 来访问文件。你是对的 defer session.Close()
在返回之前被调用。如果您使用文件 Revel 会自动关闭它,但在您的情况下,您还想关闭会话。
解决这个问题的唯一方法是制作可供 Revel 在
RenderBinary
中使用的自定义 Reader。比如:
package main
import (
"io"
"os"
"gopkg.in/mgo.v2"
)
type MongoReader struct {
io.Reader
File *os.File
Session *mgo.Session
}
func (mr *MongoReader) Read(p []byte) (n int, e error) {
return mr.File.Read(p)
}
func (mr *MongoReader) Close() {
mr.File.Close()
mr.Session.Close()
}
func main() {
mr := MongoReader{}
mr.Session, mr.File = OpenFile("abababa")
return c.RenderBinary(mr, "filename", "inline", now)
}
我没有在 Revel 上测试它,但由于代码非常简单,我认为它应该可以工作。也许你需要一些
os.File
特定的方法。