Skip to content

Instantly share code, notes, and snippets.

@xiaohui-zhangxh
Last active March 9, 2023 02:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xiaohui-zhangxh/19b4496b9093a7d4410873d3c82a7ea1 to your computer and use it in GitHub Desktop.
Save xiaohui-zhangxh/19b4496b9093a7d4410873d3c82a7ea1 to your computer and use it in GitHub Desktop.
Make liquid template's tags to be thread safe
# 使用方法:
#
# Liquid::Template.include Liquid::TemplateTagsThreadSafe
#
# Liquid::Template.with_thread_safe do
# Liquid::Template.register_tag('test', Liquid::Tag)
# Liquid::Template.tags['test'] # => Liquid::Tag
# end
#
# Liquid::Template.tags['test'] # => nil
#
module Liquid
module TemplateTagsThreadSafe
def self.included(base)
return if base.included_modules.include?(ClassMethods)
base.class_eval do
extend ClassMethods
class << self
alias_method :thread_unsafe_tags, :tags
alias_method :tags, :thread_safe_tags
end
end
end
module ClassMethods
def with_thread_safe(&)
Thread.current[:liquid_template_thread_safe] = true
copy_tags_from_thread_unsafe!
yield
ensure
Thread.current[:liquid_template_thread_safe] = false
Thread.current[:liquid_template_thread_safe_tags] = nil
end
def thread_safe?
Thread.current[:liquid_template_thread_safe] == true
end
def copy_tags_from_thread_unsafe
::Liquid::Template::TagRegistry.new.tap do |registry|
thread_unsafe_tags.each do |tag_name, klass|
registry[tag_name] = Object.const_get(klass)
end
end
end
def copy_tags_from_thread_unsafe!
Thread.current[:liquid_template_thread_safe_tags] = copy_tags_from_thread_unsafe
end
def thread_safe_tags=(tags)
if thread_safe?
Thread.current[:liquid_template_thread_safe_tags] = tags
else
thread_unsafe_tags
end
end
def thread_safe_tags
thread_safe? ? Thread.current[:liquid_template_thread_safe_tags] : thread_unsafe_tags
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment