Make Redcarpet Markdown renderer thread-safe

The Redcarpet library is not thread-safe as described in
https://github.com/vmg/redcarpet/issues/570. Since we instantiate
the Redcarpet renderer in a class variable, multiple Sidekiq threads
can access the work buffer and corrupt the state. We work around
this issue by memoizing the renderer on a thread basis.

Closes #36637
This commit is contained in:
Stan Hu 2017-09-30 14:22:52 -07:00
parent 6c33fb8466
commit 15bebda7f8
2 changed files with 19 additions and 18 deletions

View File

@ -0,0 +1,5 @@
---
title: Make Redcarpet Markdown renderer thread-safe
merge_request:
author:
type: fixed

View File

@ -1,6 +1,18 @@
module Banzai
module Filter
class MarkdownFilter < HTML::Pipeline::TextFilter
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
REDCARPET_OPTIONS = {
fenced_code_blocks: true,
footnotes: true,
lax_spacing: true,
no_intra_emphasis: true,
space_after_headers: true,
strikethrough: true,
superscript: true,
tables: true
}.freeze
def initialize(text, context = nil, result = nil)
super text, context, result
@text = @text.delete "\r"
@ -13,27 +25,11 @@ module Banzai
end
def self.renderer
@renderer ||= begin
Thread.current[:banzai_markdown_renderer] ||= begin
renderer = Banzai::Renderer::HTML.new
Redcarpet::Markdown.new(renderer, redcarpet_options)
Redcarpet::Markdown.new(renderer, REDCARPET_OPTIONS)
end
end
def self.redcarpet_options
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@redcarpet_options ||= {
fenced_code_blocks: true,
footnotes: true,
lax_spacing: true,
no_intra_emphasis: true,
space_after_headers: true,
strikethrough: true,
superscript: true,
tables: true
}.freeze
end
private_class_method :redcarpet_options
end
end
end