Is my code made well

I wanted to make an intermediate project in rust, and I chose to make a metered API system that will issue a key, and tat key can be of two types, (an admin, with unlimited assess to the API, or a standered user, with restricted assess to the API.

GitHub link: https://github.com/inyourface34456/metered-API

Your usage of loops in Ids::gen_new_id is pretty wild, same in Ids::register_hit. You should not busy loop trying to wait for a RwLock to become available. Instead of loop { rw_lock.try_read() }, just use rw_lock.read().

Oh, and if !vec.keys().collect::<Vec<_>>().contains(&&id) is pretty wasteful (vec is a HashMap—might be considered weird naming), just use if !vec.contains_key(&id).

1 Like

Wouldn't RwLock::Read panic if it is already being used? I used the busy loops to prevent panics if too many people are trying to do something at the same time.

No, it just blocks till the lock becomes available. It might return an error if the lock was poisoned.

Sorry, misread your question. When would the same thread try to acquire the lock multiple times? I couldn't see a path where this would happen, but I only skimmed your code quickly. Even then, busy looping wouldn't be the answer, as you'd loop forever, causing a deadlock. If your thread holds a write guard while you try to acquire a read guard, this should panic because this is a bug. If you just loop for ever because your read guard never becomes available due to you never getting to drop the write guard because you are stuck trying to acquire the read guard, this would cause your whole program to stall.

I am testing using this:

while true; do curl --location --request POST 'localhost:3030/get_id' --header 'Content-Type: application/json' --header 'Contente-Type: plain/text' --data-raw '"Admin"'; done

Has not crashed yet, most likely will not. I just changed the get_id function and only tested that.

Could you help me debug my app? The API keys are coming up as not registred, even though the code is there to make it run. bit that adds the key to the map:

match self.usage_list.write() {
  Ok(mut map) => {
      map.insert(correct_id, Self::gen_start_hashmap(role));
      println!("usage init sucsess");
  }
  Err(_) => {
      println!("usage init failed")
  }
}

There is no output when this code is running. All of the new code is in the GitHub repo that I linked.

I think there's just some weirdness with your brackets and the loop statement that you use to make sure you don't override an existing id:

- match self.id_list.write() {
-        Ok(mut map) => loop {
+ match self.id_list.write() {
+        Ok(mut map) => {
+            loop {
                let id: u128 = rng.gen();
                if !map.contains_key(&&id) {
                    map.insert(id, role);
                    correct_id = id;
                    break;
                }
+            }    

with your current code you break out of the whole match arm after you set correct_id, never getting to the part where you update the usage_list.

That is from cargo fmt, not my style choice. Nevertheless, I will change that.

Cargo formatted it like that, because you forgot one { before the loop statement and one } after the closing bracket of the if !map.contains_key(&&id) block.

1 Like

It worked, that was why nothing was working.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.