Is it possibile to create a static Struct with these HashMap? And is Mutex needed in this case?

I need a Store struct like this:

pub struct Store {
  pub players: HashMap<(String, i64), Player>,
  pub teams: HashMap<(String, i64), Team>,
}

impl Store {
  pub fn new() -> Self {
    Self {
      players: HashMap::new(),
      team: HashMap::new(),
    }
  }
}

The values in those HashMap are used as "shared, request-scoped memory" and then deleted (using .remove(k)).

QUESTIONs

  1. Since I don't care if two or more requests write/read the same entries at the same time (very unlikely) should I still use Mutex?

    // Like this?
    let store = Arc::new(Mutex::new(Store::new()))
    
    // Or this?
    pub fn new() -> Self {
      Self {
        players: Mutex::new(HashMap::new()),
        team: Mutex::new(HashMap::new()),
      }
    }
    
  2. Since the store is created when the application starts and is never destroyed, would it be useful to create a 'static one thus avoiding the use of Arc too?

    // Something like:
    const store: &mut Store = &mut Store::new();
    

I'm new to Rust. Thanks for your time.

You can't "not care". Race conditions are undefined behavior in Rust, so you have to care about them. You wouldn't be able to compile your code in the first place if it were racy (since mutable references are neither Send nor copiable) if you only use safe code. So yes, you have to use Mutex if you want a simple and safe solution.

You can create a static, but for the aforementioned reasons, you still have to wrap the maps in a Mutex. Since a static is effectively global, it may be trivially accessed by multiple threads at the same time, making all static muts unsafe, and requiring a Mutex for storing non-thread-safe types in a static.

Also note that const isn't the same as static. What you want here is a static, definitely not a const. Or better yet: why don't you just declare the maps in a local variable and pass it wherever it's needed? Global mutable state is bad for code readability.

1 Like

I'm trying to use this store to avoid nested structs conversion issues like:

struct Player {
  id: String,
  team: Box<Team>, // note the Box here
}

So I'm trying to use flat, plain data like:

struct Player {
  id: String,
  team_id: String,
}

but I need something to use as store.