在我的Ruby on Rails应用程序中,我需要使用Faraday
Ruby gem将大型(~ 30 MB或更大)MP4视频资产上传到Amazon S3预签名URL。此操作经常失败,并出现Faraday::ConnectionFailed: Broken pipe
错误。我想知道为什么会发生这种情况,以及如何解决它,因为我需要使这个操作更加可靠。
视频资产存储为Tempfile
,并通过PUT
请求流传输到S3预签名的URL。
这种故障不会100%发生。此操作通常在没有此失败的情况下成功,并且通常在失败引起的重试之后也将成功。如果我不得不说,失败发生在50%的时间里。
Ruby2.3.1
导轨5.0.0
法拉第0.17.3
(适配器= net/http
。我尝试将适配器更改为httpclient
,但结果出现类似的错误HTTPClient::KeepAliveDisconnected: Broken pipe
。我更喜欢使用net/http
。
相关编码
headers = { content_type: 'video/mp4', content_length: tempfile.size.to_s }
conn = Faraday.new(url: presigned_url)
resp = conn.put(presigned_url_path, tempfile, headers)
从在线研究中,我发现可能是超时,所以我尝试将以下块传递给conn.put
请求。好像没什么用。{ |req| req.options.timeout = 180 }
全栈跟踪
WARN: Faraday::ConnectionFailed: Broken pipe
WARN: /usr/local/lib/ruby/2.3.0/openssl/buffering.rb:322:in `syswrite'
/usr/local/lib/ruby/2.3.0/openssl/buffering.rb:322:in `do_write'
/usr/local/lib/ruby/2.3.0/openssl/buffering.rb:340:in `write'
/usr/local/lib/ruby/2.3.0/net/http/generic_request.rb:206:in `copy_stream'
/usr/local/lib/ruby/2.3.0/net/http/generic_request.rb:206:in `send_request_with_body_stream'
/usr/local/lib/ruby/2.3.0/net/http/generic_request.rb:123:in `exec'
/usr/local/bundle/gems/aws-sdk-core-3.15.0/lib/seahorse/client/net_http/patches.rb:28:in `block in new_transport_request'
/usr/local/bundle/gems/aws-sdk-core-3.15.0/lib/seahorse/client/net_http/patches.rb:27:in `catch'
/usr/local/bundle/gems/aws-sdk-core-3.15.0/lib/seahorse/client/net_http/patches.rb:27:in `new_transport_request'
/usr/local/lib/ruby/2.3.0/net/http.rb:1407:in `request'
/usr/local/lib/ruby/2.3.0/net/http.rb:1400:in `block in request'
/usr/local/lib/ruby/2.3.0/net/http.rb:853:in `start'
/usr/local/lib/ruby/2.3.0/net/http.rb:1398:in `request'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/adapter/net_http.rb:87:in `perform_request'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/adapter/net_http.rb:43:in `block in call'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/adapter/net_http.rb:92:in `with_net_http_connection'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/adapter/net_http.rb:38:in `call'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/request/url_encoded.rb:15:in `call'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/rack_builder.rb:143:in `build_response'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/connection.rb:387:in `run_request'
/usr/local/bundle/gems/faraday-0.17.3/lib/faraday/connection.rb:175:in `put'
1条答案
按热度按时间vngu2lb81#
您的错误似乎是由网络中断引起的。Broken pipe是一个特定的错误,当客户端试图从服务器关闭的套接字读取数据时发生。
您可以尝试以下几种方法来解决此问题:
1.增加超时值。
超时值是客户端在放弃之前等待服务器响应的时间量。
2.实现重试机制。
您可以使用Faraday Retry plugin自动重试失败的请求,但需要确保与法拉第0.17.3版本的兼容性。