this post was submitted on 23 Aug 2023
19 points (100.0% liked)

Rust

7158 readers
20 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 2 years ago
MODERATORS
 

I've been trying to use OneCell, but I keep having errors trying to set it up to handle a mutable vector that I can push to.

I know there's going to be some answers telling me maybe not to use a singleton, but the alternative of passing a vector all around throughout my code is not ergonmic at all.

I've tried lots of things, but this is where I'm at right now. Specifically I'm just having trouble initializing it.

`/**

  • LOG_CELL
  • Stores a vec of Strings that is added to throughout the algorithm with information to report
  • To the end user and developer */ pub static LOG_CELL: OnceLock<&mut Vec> = OnceLock::new();

pub fn set_log() { LOG_CELL.set(Vec::new()); }

pub fn push_log(message: String) { if let Some(vec_of_messages) = LOG_CELL.get() { let something = *vec_of_messages; something.push(message); } } `

top 8 comments
sorted by: hot top controversial new old

You can wrap the Vec in a Mutex

[–] pranaless@beehaw.org 3 points 2 years ago (1 children)

OnceLock is the wrong primitive for this. Use a Mutex or an RwLock instead? You can initialize either of them with an empty array at declaration, so you don't need the set_log function. In push_log, do a .lock().unwrap() for a mutex or .write().unwrap() for an rwlock to get mutable access to the vector.

[–] nerdblood@programming.dev 1 points 2 years ago

Nice, thanks... looking into these now.

[–] ActuallyRuben@actuallyruben.nl 2 points 2 years ago

Can't you just use the get_or_init method instead of get inside the push_log method? This would initialize the cell on first use. You'd still need a Mutex inside of it to acquire a mutable reference to the vector.

[–] frankfurt_schoolgirl@hexbear.net 2 points 2 years ago (1 children)

Is the Singleton accessed by one thread or many?

If it's one thread, couldn't you just wrap the Vec in an Rc and then clone your singleton every time you need it in a new scope?

If it's many, you should use channels and a dedicated logging thread imo.

[–] nerdblood@programming.dev 1 points 2 years ago (1 children)

One for now, theoretically many later.

Nice I've never used Rc. Maybe now's my chance to look into it.

[–] RunAwayFrog@sh.itjust.works 3 points 2 years ago* (last edited 2 years ago) (1 children)

Look into Arc, RwLock, and Mutex too.

Later, check out parking_lot and co. and maybe async stuff too.

[–] nerdblood@programming.dev 1 points 2 years ago

Async I have a handle on, but I'll take a look at the others for sure.