【问题标题】:AppEngine IO Copy issue results in "API error 10 (file: FILE_NOT_OPENED)"AppEngine IO Copy 问题导致“API 错误 10(文件:FILE_NOT_OPENED)”
【发布时间】:2015-04-24 14:55:33
【问题描述】:

我的 GoLang AppEngine 代码正在解压缩 ZIP 文件,然后将每个文件保存为 BlobStore 内容。我已经看到保存数据需要 30 多秒,然后失败并显示“API 错误 10(文件:FILE_NOT_OPENED)”。正在写入的未压缩文件的大小约为 1.5 兆字节。以下是从 Zip 阅读器复制到新 BlogStore 项目的代码:

func storeBlob(c appengine.Context, rc io.Reader, mimeType string) (appengine.BlobKey, error) {

c.Infof("Creating new blob of type: [%v]", mimeType)
var key appengine.BlobKey
w, err := blobstore.Create(c, mimeType)
if err != nil {
    return "", err
}

c.Infof("Copying blob data")
_, err = io.Copy(w, rc)
if err != nil {
    return "", err
}

c.Infof("Closing Blob")
err = w.Close()
if err != nil {
    return "", err
}

c.Infof("Getting Blob Key")
key, err = w.Key()
if err != nil {
    return "", err
}
return key, nil

}

生产应用引擎服务器锁定 30 秒,然后在 io.Copy 调用上报告错误。有关如何解决此问题的任何想法?

【问题讨论】:

    标签: google-app-engine go


    【解决方案1】:

    此错误是因为您的请求超时。 Create 发出一个类似于 this 的协议缓冲区请求:

    oreq := &filepb.OpenRequest{
        Filename:      res.Filename,
        ContentType:   filepb.FileContentType_RAW.Enum(),
        OpenMode:      filepb.OpenRequest_APPEND.Enum(),
        ExclusiveLock: proto.Bool(true),
    }
    

    对应的definition

    type OpenRequest struct {
        Filename             *string                      `protobuf:"bytes,1,req,name=filename" json:"filename,omitempty"`
        ContentType          *FileContentType_ContentType `protobuf:"varint,2,req,name=content_type,enum=files.FileContentType_ContentType" json:"content_type,omitempty"`
        OpenMode             *OpenRequest_OpenMode        `protobuf:"varint,3,req,name=open_mode,enum=files.OpenRequest_OpenMode" json:"open_mode,omitempty"`
        ExclusiveLock        *bool                        `protobuf:"varint,4,opt,name=exclusive_lock,def=0" json:"exclusive_lock,omitempty"`
        BufferedOutput       *bool                        `protobuf:"varint,5,opt,name=buffered_output,def=0" json:"buffered_output,omitempty"`
        OpenLeaseTimeSeconds *int32                       `protobuf:"varint,6,opt,name=open_lease_time_seconds,def=30" json:"open_lease_time_seconds,omitempty"`
        XXX_unrecognized     []byte                       `json:"-"`
    }
    

    通知OpenLeaseTimeSeconds 未设置。默认为 30 秒:

    const Default_OpenRequest_OpenLeaseTimeSeconds int32 = 30
    

    所以它可能正在关闭你下面的连接。

    你有两个选择:

    1. 编写您自己的 Create 方法,将租用时间设置为大于 30 秒。您最多可以在 60 秒后收到您的请求 will be killed,在这种情况下,您需要使用 Task Queue

    2. API 已弃用:

      警告:此处用于将文件写入 Blobstore 的 Files API 功能已被弃用,并且将在未来某个时间被移除,以支持将文件写入 Google Cloud Storage 并使用 Blobstore 来提供服务。如需更多信息,请访问谷歌云存储。

      所以也许你应该改用谷歌存储。

    【讨论】:

    • 我会接受这个答案,因为我认为 Google 在弃用文件 API 时一直在更改它并导致奇怪的 IO 错误。
    猜你喜欢
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 2018-09-30
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多