# Thread unsafe lazy initialization in PostActionType

**URL:** https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447
**Category:** Bug
**Created:** [April 27, 2022, 3:28pm UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447 "2022-04-27T15:28:22Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![bjfish](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bjfish/32/188318_2.png) [@bjfish](https://meta.discourse.org/u/bjfish)
#### Post date: [April 27, 2022, 3:28pm UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/1 "2022-04-27T15:28:22Z")

</div>

While using discourse in a multi-threaded Ruby implementation and server (TruffleRuby/Puma), errors are produced by the unsafe hash usage in flag settings and this lazy initialization pattern needs to avoid assigning twice:

> <https://github.com/discourse/discourse/blob/14b09c9909e9f161136218ba08c937d6adee60ba/app/models/post_action_type.rb#L17>

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [April 28, 2022, 2:50am UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/2 "2022-04-28T02:50:15Z")

</div>

Does a simple call to `PostActionType.flag_settings` in an initializer resolve the issue? (eg: just insert here: [discourse/config/initializers/000-mini\_sql.rb at 3e0cb8ea47ea27cb3b564ac10656884739e4d78c · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/3e0cb8ea47ea27cb3b564ac10656884739e4d78c/config/initializers/000-mini_sql.rb#L4-L4) temporarily)

I guess we could synchronize this block as well. Are there any other big red flags truffle is raising?

---

<div class="post-metadata">

### Author: ![eregon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eregon/32/188324_2.png) [@eregon](https://meta.discourse.org/u/eregon)
#### Post date: [April 28, 2022, 12:08pm UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/3 "2022-04-28T12:08:21Z")

</div>

Yes, that should work.  
Is there any reason to initialize this lazily?  
Initializing it eagerly would avoid any synchronization issue and be slightly faster to access as well as simpler.

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [May 2, 2022, 7:55am UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/4 "2022-05-02T07:55:01Z")

</div>

Honestly I am not sure if this lazy init makes sense at all here as well, we have a hook for plugins to replace the entire set of flags, but that would fire prior to the initializer.

@roman any concerns with an eager init here? I guess the trivial fix is:

```plaintext
class << self

  def flag_settings
     ...
   end 
end

flag_settings 

```

I am thinking that the big reason this happened is that ruby does not ship a clean pattern for class initializers so it pushes devs towards inventing own/using lazy.

---

<div class="post-metadata">

### Author: ![eregon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eregon/32/188324_2.png) [@eregon](https://meta.discourse.org/u/eregon)
#### Post date: [May 2, 2022, 10:13am UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/5 "2022-05-02T10:13:45Z")

</div>

It could also be done like this, that would notably avoid reading the ivar twice and make it clearer it’s eager-initialized (the logic could also be in a `initial_flag_settings` helper method for organization of course):

```ruby
  class << self
    attr_reader :flag_settings
  end

  @flag_settings = FlagSettings.new
  @flag_settings.add(
    3,
    :off_topic,
    notify_type: true,
    auto_action_type: true,
  )
  # ...

```

---

<div class="post-metadata">

### Author: ![Roman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/roman/32/157504_2.png) [@Roman](https://meta.discourse.org/u/Roman)
#### Post date: [May 2, 2022, 3:27pm UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/6 "2022-05-02T15:27:54Z")

</div>

Yeah, I think eager initializing would be safe here. It also shouldn’t conflict with the plugin API, which is rarely used.

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [May 18, 2022, 6:56pm UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/7 "2022-05-18T18:56:32Z")

</div>

Here’s a PR:

[https://github.com/discourse/discourse/pull/16864](https://github.com/discourse/discourse/pull/16864)

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [May 27, 2022, 10:00pm UTC](https://meta.discourse.org/t/thread-unsafe-lazy-initialization-in-postactiontype/225447/8 "2022-05-27T22:00:45Z")

</div>

This topic was automatically closed after 4 days. New replies are no longer allowed.
