-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible race condition in the Maildown::MarkdownEngine.default_html_block method #40
Comments
Thanks for the note. The reason that it's a lazy load is that people can install their own markdown rendering engines if they want (though honestly I have no proof that anyone is doing that. I think the fix would be requiring the gem at boot time, but rescuing in-case it does not exist. The only other thing I could think of is to use a mutex to block multiple clients from trying to require at the same time, but that increases a tiny bit of runtime overhead that I don't think is needed. |
Do you know if Autoload fixes this issue, or if I need to mutex it? |
I was late by a hair, but you may have to mutex it. There is a thread-safety issue in cc @ko1 |
Looks like it is threadsafe https://twitter.com/schneems/status/978705647301746688 |
It's supposed to have been thread safe since 2.0 headius/thread_safe#15 (comment) |
I looked into what has caused the bug ruby/did_you_mean#102. One thing I noticed is that in the maildown gem, the
kramdown
gem is lazily loaded on the fly, which adds a handful of constants dynamically. In an extreme condition, this may cause a race condition. Consider the following scenario where a Sidekiq instance runs two threads (workders) that attempt to run an email delivery job:MarkdownEngine.default_html_block
MarkdownEngine.default_html_block
require 'kramdown'
for the first timeKramdown
constant but doesn't reach the line 74 that addsKramdown::Document
unless defined? Kramdown
(now evaluates tounless true
)html_block.call
on the proc that has a reference to theKramdown::Document
that does not exist yetIn this scenario, the thread 2 would raise a
NameError
because theKramdown
constant is loaded but theKramdown::Document
is not. Also, it would only occur once after a cold reboot since the constant would be available once it's loaded by the thread 1.I wasn't sure what fixes you'd prefer, so just wanted to bring this up. Thanks!
The text was updated successfully, but these errors were encountered: