首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby :使用google-api-ruby-client SDK上传文件到Google drive失败,并出现Timeout::Error

Ruby :使用google-api-ruby-client SDK上传文件到Google drive失败,并出现Timeout::Error
EN

Stack Overflow用户
提问于 2012-11-28 18:36:48
回答 3查看 3.6K关注 0票数 4

我在Rails应用程序中使用google-api-ruby-client与Google Drive进行交互。所有的基本功能,如列出文件夹中的文件,获取,移动,复制和删除文件,创建新文件夹等都工作得很好。

但是,上传新文件总是失败,并显示Timeout::Error

我从我的网站(multipart/form-data)收到要作为常规文件上传的文件,这就是我上传到Google drive的方式

代码语言:javascript
复制
result = nil
new_file_obj = google_drive.files.insert.request_schema.new({
  'title' => file_name,
  'mimeType' => file_mime_type,
  'parents' => [{'id' => current_folder_id}]
})

file_content = Google::APIClient::UploadIO.new(new_file.tempfile, file_mime_type, file_name)

result = google_client.execute(
    api_method: google_drive.files.insert,
    body_object: new_file_obj,
    media: file_content,
    parameters: {
      'uploadType' => 'multipart',
      'alt' => 'json'
    }
  )

这里的new_file是客户端上传的文件。new_file.tempfile提供了一个Tempfile类型的对象。

execute方法再也没有返回,最终我得到了一个Timeout::Error异常。这是相关的堆栈跟踪:

代码语言:javascript
复制
/lib/ruby/1.9.1/net/protocol.rb:140:in `rescue in rbuf_fill'
/lib/ruby/1.9.1/net/protocol.rb:134:in `rbuf_fill'
/lib/ruby/1.9.1/net/protocol.rb:116:in `readuntil'
/lib/ruby/1.9.1/net/protocol.rb:126:in `readline'
/lib/ruby/1.9.1/net/http.rb:2211:in `read_status_line'
/lib/ruby/1.9.1/net/http.rb:2200:in `read_new'
/lib/ruby/1.9.1/net/http.rb:1183:in `transport_request'
/lib/ruby/1.9.1/net/http.rb:1169:in `request'
/lib/ruby/1.9.1/net/http.rb:1162:in `block in request'
/lib/ruby/1.9.1/net/http.rb:627:in `start'
/lib/ruby/1.9.1/net/http.rb:1160:in `request'
/lib/ruby/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/adapter/net_http.rb:74:in `perform_request'
/lib/ruby/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/adapter/net_http.rb:37:in `call'
/lib/ruby/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/request/url_encoded.rb:14:in `call'
/lib/ruby/gems/1.9.1/gems/google-api-client-0.5.0/lib/google/api_client/request.rb:154:in `send'
/lib/ruby/gems/1.9.1/gems/google-api-client-0.5.0/lib/google/api_client.rb:546:in `execute'

我按照下面的例子写了这段代码:https://developers.google.com/drive/examples/ruby#saving_new_files,我在这里遗漏了什么?

我尝试上传的文件是一个小的png图像。该文件可以正确地到达我的web应用程序,因为如果我将其写入磁盘,我就可以查看该文件。谷歌服务器绝对没有宕机,因为我可以从drive.google.com上传一个文件。这也意味着我的网络足够好。

那么到底是什么导致了超时呢?

对此相同异常的一种解决方案被提及为增加read_timeout (http://stackoverflow.com/questions/10011387/rescue-in-rbuf-fill-timeouterror-timeouterror)。这是我应该做的吗?如果是这样的话,我该如何在这里使用google-api-ruby-client sdk呢?

EN

回答 3

Stack Overflow用户

发布于 2012-12-01 03:24:29

根据一些快速实验,可能只是临时文件没有倒回以进行读取。我修改了快速入门示例以从临时文件中读取,并能够重现错误。例如:

代码语言:javascript
复制
tmp = Tempfile.new('foo')
tmp.write("hello world")

media = Google::APIClient::UploadIO.new(tmp, 'text/plain', 'foo.txt')
file = drive.files.insert.request_schema.new({
  'title' => 'My document',
  'description' => 'A test document',
  'mimeType' => 'text/plain'
})
result = client.execute(
  :api_method => drive.files.insert,
  :body_object => file,
  :media => media,
  :parameters => {
    'uploadType' => 'multipart',
    'alt' => 'json'})

这将在挂起大约30秒后产生相同的堆栈跟踪。但是,添加对rewind的调用来重置临时文件会使其正常工作

代码语言:javascript
复制
tmp = Tempfile.new('foo')
tmp.write("hello world")
tmp.rewind # Reset for reading...

试一试,看看它是否能解决你的问题。

票数 1
EN

Stack Overflow用户

发布于 2013-04-09 22:09:31

看着https://github.com/google/google-api-ruby-client/blob/master/lib/google/api_client.rb#L532-560

您可以将Faraday连接传递给execute方法。就像这样

代码语言:javascript
复制
conn = Faraday.default_connection
conn.options[:timeout] = 500 

result = google_client.execute(
api_method: google_drive.files.insert,
body_object: new_file_obj,
media: file_content,
parameters: {
  'uploadType' => 'multipart',
  'alt' => 'json'
 },
connection: conn
)

这将增加Net:HTTP超时。

票数 0
EN

Stack Overflow用户

发布于 2021-01-20 14:12:31

显然,Google关于使用Ruby上传文件到文件夹的文档还没有文档化。它的实现方式如下。

代码语言:javascript
复制
class DriveUpload
    def self.process
            drive_service = Google::Apis::DriveV3::DriveService.new

            drive_service.authorization = Google::Auth::ServiceAccountCredentials.make_creds(
            json_key_io: File.open('client_secret.json'),
            scope: Google::Apis::DriveV3::AUTH_DRIVE)
            meta_data = Google::Apis::DriveV3::File.new(name:'README_ONDRIVE.md',parents:["1gUxa7_9kbaBX_iofwUYKU_3BFXbBu6Ip"])

            file = drive_service.create_file(meta_data, upload_source: 'README.md',content_type: 'text/plain')

    end
end

请注意,父文件夹是指驱动器中的文件夹(您与服务帐户共享的文件夹)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13603057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档