如何重现/清理混乱的POST参数,以避免YDelay_job的YAML序列化问题? [英] How to reproduce/sanitize messy POST params to avoid YAML serialization issues with delayed_job?
问题描述
今天,每次我开始使用 delayed_job
工人时,该过程都会立即且无声地终止。
之后经过一些调查(并发现了 delayed_job
的前台模式),我终于发现问题出在 delayed_job
已经序列化了我的活动记录对象,并在YAML加载部分触发了异常:
Psych :: SyntaxError:(< unknown> ):在这种情况下,在/Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb的第7行第14列
中不允许使用映射键: 203:来自/Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb中的'parse'
:203:in`parse_stream'
来自/Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:151:在'parse'
来自/Users/mick/.rvm /rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:127:在/Users/mick/.rvm/gems/ruby-1.9.3-的'load'
中p448 / gems / safe_yaml-0.9.7 / lib / safe_yaml.rb:144:在`load_with_options'$中来自(irb)的b $ b:111来自/Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands/console.rb的b $ b: 47:在/users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands/console的'start'
中.rb:8:in从/Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands.rb:41:in`< top( >'
from script / rails:6:in`require'
from script / rails:6:in`< main>'
尝试 delayed_job
时发生的情况:
YAML.load(my_job.handler)
找到有问题的 Delayed :: Backend :: ActiveRecord :: Job
实例后,一个放入my_job.handler
将显示:
对象:!ruby / ActiveRecord:MyActiveRecord
属性es:
id:7648
...一些好东西...
my_field:? bla bla bla
...一些其他好东西...
method_name::mail
args:[]
我首先认为这是一个编码问题,但我意识到'?'字符是真实的'?'字符(即值63),而不是对无法识别的字符的误解。 / p>
然后,我尝试创建活动记录类的新实例,其 my_field
值? Totot
,然后YAML如下所示:
object:!ruby / ActiveRecord:MyActiveRecord
属性:
id:7648
...一些好东西...
my_field:! ’? bla bla bla'
...一些其他好东西...
method_name::mail
args:[]
和 YAML.load(...)
成功运行。
所以我的问题是:
- 任何知道我如何在数据库中获取凌乱的YAML的信息吗?
- 有什么主意应该清理参数以避免这种问题吗?
- 有什么主意如何尝试在单元测试中重现它? (以确保我实际上已通过步骤2对其进行了修复)
详细说明@ house9建议的内容:
请勿执行以下操作(即使delay_job的git repo建议作为示例)
Notifier.delay.signup(@user)
class NotifierMailer< ActionMailer :: Base
def注册(用户)
结束
结束
因为这将尝试对 @user
进行yaml编码(这可能会导致问题)
但是,任何时候您有一个具有ID的对象(尤其是AR对象),则在调用延迟的作业时应传递该ID,并在以后检索它:
Notifier.delay.signup(@ user.id)
class NotifierMailer< ActionMailer :: Base
def注册(id)
@user = User.find_by_id(id)
结束
结束
Today, every time I was starting delayed_job
workers, the process would die immediately and silently.
After some investigation (and finding out about the foreground mode of delayed_job
), I finally found out the problem was the way delayed_job
had serialized my active record object was triggering an exception on the YAML load part:
Psych::SyntaxError: (<unknown>): mapping keys are not allowed in this context at line 7 column 14
from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:203:in `parse'
from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:203:in `parse_stream'
from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:151:in `parse'
from /Users/mick/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/psych.rb:127:in `load'
from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/safe_yaml-0.9.7/lib/safe_yaml.rb:144:in `load_with_options'
from (irb):111
from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands/console.rb:47:in `start'
from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands/console.rb:8:in `start'
from /Users/mick/.rvm/gems/ruby-1.9.3-p448/gems/railties-3.2.16/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Which happened when delayed_job
tried:
YAML.load(my_job.handler)
(others had the same issue before me)
After finding the problematic Delayed::Backend::ActiveRecord::Job
instance, a puts my_job.handler
would show:
object: !ruby/ActiveRecord:MyActiveRecord
attributes:
id: 7648
... some good stuff ...
my_field: ? bla bla bla
... some other good stuff ...
method_name: :mail
args: []
I first thought it was an encoding issue but I realized the '?' character was a real '?' character (i.e. value 63) and not a misinterpretation of an unrecognized character.
Then I tried to create a new instance of my active record class with a my_field
value of ? Totot
but then the YAML looked like the following:
object: !ruby/ActiveRecord:MyActiveRecord
attributes:
id: 7648
... some good stuff ...
my_field: ! '? bla bla bla'
... some other good stuff ...
method_name: :mail
args: []
and the YAML.load(...)
ran successfully.
So my questions are:
- Any idea how I got a messy YAML in my database?
- Any idea how I should sanitize my params to avoid such a problem?
- Any idea how I can try to reproduce this in a unit test? (to be sure I'm actually fixing it with step 2)
A detailed explanation of what @house9 is suggesting:
Do NOT do the following (even though the delayed_job's git repo suggests is as example)
Notifier.delay.signup(@user)
class NotifierMailer < ActionMailer::Base
def signup(user)
end
end
as this will attempt to yaml encode @user
(which can cause issues)
But rather, any time you have an object (especially an AR object) that has an id, you should pass the id when calling the delayed job and retrieve it later:
Notifier.delay.signup(@user.id)
class NotifierMailer < ActionMailer::Base
def signup(id)
@user = User.find_by_id(id)
end
end
这篇关于如何重现/清理混乱的POST参数,以避免YDelay_job的YAML序列化问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!