问题描述
我刚刚在我打电话的地方发现了这个错误
MyJob.perform_later(request.body.read)
有一个 sidekiq active_job 作业,
调用 request.body.read
返回一些 json,我认为在某些情况下它可能包含 UTF-8 字符(即 € 符号),
在这种情况下我得到
Encoding::UndefinedConversionError Exception: "\xE2" from ASCII-8BIT to UTF-8
我知道 sidekiq 建议不要使用复杂或冗长的作业参数,最佳实践解决方法是什么?
我能想到的是在将字符串传递给作业之前对其进行 base64 编码(但这会使 sidekiq 的时间更长,我不确定这会不会有问题) 或者将实际的 json 文本存储在 db 表中,然后将新行的 id 传递给作业。这肯定会奏效,但对我来说看起来有点矫枉过正。
有什么建议吗?
解决方法
Sidekiq 将使用 JSON.generate
来序列化作业参数。这是您可以在控制台中运行的 ASCII-8BIT
字符串发生的情况的示例:
arg = "Example with € character".force_encoding('ASCII-8BIT')
JSON.generate([arg])
Encoding::UndefinedConversionError ("\xE2" from ASCII-8BIT to UTF-8)
一种选择是遵循 this answer 并在将其传递到 perform_later
之前强制编码为 UTF-8。然后它将正确序列化:
arg = "Example with € character".force_encoding('ASCII-8BIT')
arg.force_encoding('UTF-8')
JSON.generate([arg])
=> "[\"Example with € character\"]"
所以你想要这样的东西:
MyJob.perform_later(request.body.read.force_encoding('UTF-8'))