Ruby 用于发送到 Sidekiq / Redis 的 ZIP 文件编码

Ruby ZIP file encoding for sending to Sidekiq / Redis

我使用以下代码构建一个 ZIP 文件:

def compress_batch(directory_path)
  zip_file_path = File.join( File.expand_path("..", directory_path), SecureRandom.hex(10))
  Zip::File.open(zip_file_path, Zip::File::CREATE) do |zip_file|
    (Dir.entries(directory_path) - %w(. ..)).each do |file_name|
      zip_file.add file_name, File.join(directory_path, file_name)
    end
  end

  result = File.open(zip_file_path, 'rb').read
  File.unlink(zip_file_path)
  result
end

我将该 ZIP 文件存储在内存中:

@result = Payoff::DataFeed::Compress::ZipCompress.new.compress_batch(source_path)

我把它放到一个hash中:

options = {
  data: @result
}

然后我使用 perform_async:

将其提交给我的 SideKiq 工作人员
DeliveryWorker.perform_async(options)

并得到以下错误:

[DEBUG]   Starting store to: { "destination" => "sftp", "path" => "INBOUND/20191009.zip" }
Encoding::UndefinedConversionError: "\xBA" from ASCII-8BIT to UTF-8
from ruby/2.3.0/gems/activesupport-4.2.10/lib/active_support/core_ext/object/json.rb:34:in `encode'

但是,如果我使用 .new.perform 而不是 .perform_async,绕过 SideKiq,它工作正常!

DeliveryWorker.new.perform(options)

我最好的猜测是我的编码有问题,以至于当作业转到 SideKiq / Redis 时,它就崩溃了。我应该如何编码它?我需要更改 ZIP 文件的创建吗?也许我可以在提交到 SideKiq 时转换编码?

Sidekiq 将参数序列化为 JSON。您正在尝试将二进制数据填充到 JSON 中,它只支持 UTF-8 字符串。如果您希望通过 Redis 传递数据,则需要对数据进行 Base64 编码。

require 'base64'

encoded = Base64.encode64(filedata)