При использовании Discourse в многопоточной реализации Ruby и сервере (TruffleRuby/Puma) возникают ошибки из-за небезопасного использования хешей в настройках флагов. Этот паттерн ленивой инициализации должен исключать двойное присваивание:
Решит ли проблему простой вызов PostActionType.flag_settings в инициализаторе? (Например, просто вставьте это сюда: discourse/config/initializers/000-mini_sql.rb at 3e0cb8ea47ea27cb3b564ac10656884739e4d78c · discourse/discourse · GitHub временно)
Думаю, мы могли бы также синхронизировать этот блок. Есть ли ещё какие-то серьёзные предупреждения, которые поднимает Truffle?
Да, это должно сработать.
Есть ли какая-то причина для ленивой инициализации?
Эагная инициализация позволит избежать проблем синхронизации, обеспечит немного более быстрый доступ, а также будет проще в реализации.
Честно говоря, я не уверен, что такая ленивая инициализация вообще имеет смысл здесь. У нас есть хук для плагинов, позволяющий заменить весь набор флагов, но он срабатывает до инициализатора.
@roman, есть ли какие-то возражения против eager-инициализации здесь? Думаю, самое простое решение — это:
class << self
def flag_settings
...
end
end
flag_settings
Мне кажется, главная причина этого — в том, что в Ruby нет чистого паттерна для инициализаторов класса, поэтому разработчиков подталкивают к тому, чтобы изобретать свои решения или использовать ленивую инициализацию.
Это также можно сделать так, что это заметно исключит двойное чтение ivar и сделает более явным, что инициализация происходит сразу (логика, конечно же, также может быть вынесена в вспомогательный метод initial_flag_settings для лучшей организации):
class << self
attr_reader :flag_settings
end
@flag_settings = FlagSettings.new
@flag_settings.add(
3,
:off_topic,
notify_type: true,
auto_action_type: true,
)
# ...
Да, я думаю, что eager-инициализация здесь будет безопасна. Это также не должно конфликтовать с API плагинов, которое используется редко.
Вот PR:
Эта тема была автоматически закрыта через 4 дня. Новые ответы больше не принимаются.