4 ms·
I‘m on Mobile right now, but in that case you’d wrap your db in a Arc<RwLock<~>> (or Rc<> if you don’t need concurrency.). Then, anytime you need to access the
by terhechte 5y ago
I‘m on Mobile right now, but in that case you’d wrap your db in a Arc<RwLock<~>> (or Rc<> if you don’t need concurrency.). Then, anytime you need to access the DB, you’d try to lock the RwLock’s Writer or reader.
- andrepd 5y agoBut isn't this imposing a runtime cost on safety? Isn't rust all about safety and performance?
- opportune 5y agoUnder the hood most (all? Hesitate to say all but probably all) clients will have some form of mutex lock to at the very least control access to the file (eg socket) they use to pass messages to the server. If you find an example otherwise I’d like to hear it, though do keep in mind the mutex may not even be implemented in userspace. Which is to say, accessing a client may or may not be thread safe (depending on the client implementation) but assuming it’s not a multiplexing client, it almost certainly uses some kind of locking mechanism under the hood Even if it is a multiplexing client, if you saturate the internal clients you will either need to wait for a client to stop writing to its socket (through perhaps a lockless consumer model) or create a new internal client (slow).
- jjice 5y agoYes, but I can see it being worth while when you can spare the tiny amount of overhead, especially in a project that's meant to be self hosted like this.
- vngzs 5y agoIn Rust, abstractions tend to be zero-cost, but things that actually impact runtime are as fast as you write them. Concurrency problems don't magically disappear because your language can check for them. You still need to use memory-safe patterns, but the compiler will force your hand and prevent you from doing unsafe things accidentally. In the end, this makes it far easier to build correct, concurrent applications. If you decide to try some fancy new pattern that doesn't require locking, the compiler can guarantee the memory safety of your new implementation.
- terhechte 5y agoIt is a matter of tradeoffs and requirements. Arc<RwLock> is a solid solution for most use cases. If the requirement is (just making up an unlikely extreme scenario) to have a huge amount of threads which constantly lock the RwLock a better solution might be to just open multiple connections per database, each per thread. SQLite, for example, is build with this in mind. For a reasonable amount of locking, The Arc / RwLock dance offers good performance (other languages, like Swift, use something like Arc for every property access (although the compiler tries to optimise it away)). The safety is actually better because you're forced to think about the failure case. I don't have good memories of Objective-C where some Foundation calls don't throw (in they don't have an error parameter), but just throw random undocumented exceptions. (Not saying that some Rust calls don't panic, but knowing that something can go wrong is much better than learning about it in production).