Heroku:通过 rake 任务解压 Gzip 文件失败

Heroku: Unpacking a Gzip file through a rake task fails

我正在使用 Rails 5.2ruby 2.5.1 并将我的应用程序部署到Heroku

我 运行 在尝试 运行 本地 rake 任务时遇到了问题。该任务调用一个 API,它以 *.gz 文件响应,保存它,压缩,然后使用检索到的 JSON 填充数据库,最后删除 *.gz 文件。任务 运行 在开发中很顺利,但在生产中调用时。打印到控制台的最后一行是 'Unzipping the file...',所以我猜问题出自 zlib 库。

companies_list.rake

require 'json'
require 'open-uri'
require 'zlib'
require 'openssl'
require 'action_view'

include ActionView::Helpers::DateHelper

desc 'Updates Company table'
task update_db: :environment do
  start = Time.now
  zip_file_url = 'https://example.com/api/download'

  TEMP_FILE_NAME = 'companies.gz'

  puts 'Creating folders...'

  tempdir = Dir.mktmpdir
  file_path = "#{tempdir}/#{TEMP_FILE_NAME}"

  puts 'Downloading the file...'

  open(file_path, 'wb') do |file|
    open(zip_file_url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE }) do |uri|
      file.write(uri.read)
    end
  end

  puts 'Download complete.'
  puts 'Unzipping the file...'

  gz = Zlib::GzipReader.new(open(file_path))
  output = gz.read
  @companies_array = JSON.parse(output)

  puts 'Unzipping complete.'

  (...)
end

有没有其他人运行遇到类似的问题并且知道如何让它工作?

您的代码片段并未表明您曾经关闭过 GzipReader。通常最好将 IO 包装在块中以确保它们被正确关闭。此外,open 方法可能不是您想要的方法,因此只需让 GzipReader 为您打开文件并发送 file_path 即可。

Zlib::GzipReader.new(file_path) do |gz|
  output = gz.read
  @companies_array = JSON.parse(output)
end

问题与内存限制有关,而不是 Gzip 解压缩(这就是为什么问题只发生在生产环境中)。

解决方案是使用 Json::Streamer 这样整个文件就不会一次加载到内存中。

这是关键部分:(在问题中发布的代码之后)

  puts 'Updating the Company table...'
  streamer = Json::Streamer.parser(file_io: file, chunk_size: 1024)  # customize your chunk_size
  streamer.get(nesting_level: 1) do |company|
    (do your stuff with the API data here...)
  end
end