How to make static pool of created objects


#1

Hello, I am new to rust-lang.
I am trying to write Python extension using PyO3 crate.
I wish to create some data structures in rust and store them in HashMap with the String keys. Python code should then provide String key when calling rust functions to manipulate or get information from data structures that are created and kept in rust.

Here is playground code:
https://play.rust-lang.org/?gist=c62ba1ecc719a5c7fc265675d40dc613&version=stable&mode=debug&edition=2015

Compiler refuses to initialize static variables calling HashMap::new. I found suggestion to use lazy_static which I tried but I don’t know how to have mutable static in lazy_static. All the examples show only once created and never changed static variables.

Vitalije


#2

lazy_static is the way to go to initialize non-trivial static data.

Rust requires everything to be thread-safe (even if you’re not using threads, the concept of a single-threaded program doesn’t exist to Rust). Because static variables could be accessed from multiple threads at once, you have to make static variables thread safe. One way to do it is to put the value in Mutex.


#3

If you really want to make global mutable variable, you can. However, as soon as you do that, the compiler cannot enforce thread safety when accessing that variable, and so you’d have to use unsafe statements to read or write it. And why program in Rust if you’re going to circumvent its benefits?

kornel is correct, you should take your global mutable state, wrap it in a Mutex, and then initialize it in a lazy_static. The Mutex is an implementation of internal mutability; a &Mutex<T> can be turned into a &mut T.

Now, I believe that Python is inherently single-threaded, which means that it actually would be safe to have a global mutable variable. Of course, the Rust compiler cannot tell that. What I would do, then, is instead of using mutex.lock(), which will block if the mutex is already locked, use mutex.try_lock().unwrap(), which will panic if the mutex is already locked. If Python is single-threaded, that should never panic, and if it does panic, you know something’s off.


#4

Thanks, I’ve just found example in cookbook rust.
https://rust-lang-nursery.github.io/rust-cookbook/basics.html#maintain-global-mutable-state

I wander if RwLock is any better choice than Mutex?
Vitalije


#5

Thanks for the explanation. I haven’t thought of that but I did plan to use rust threads to operate on the data held by rust by releasing GIL. Python will send requests and read answers using its (single thread).

Vitalije


#6

You can access mutable statics in unsafe blocks. It will be correct and safe if you ensure yourself that you only do it when holding python’s GIL.