Fakultas Ilmu Komputer UI

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • daffa.aqil31/bambangshop-receiver
1 result
Show changes
Commits on Source (6)
......@@ -139,3 +139,4 @@ $RECYCLE.BIN/
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/rust,linux,windows,database,rust-analyzer,visualstudiocode,venv,dotenv,virtualenv,direnv,jenv,git
.qodo
......@@ -85,5 +85,12 @@ This is the place for you to write reflections:
### Mandatory (Subscriber) Reflections
#### Reflection Subscriber-1
### 1. Why is `RwLock<>` necessary, and why not use `Mutex<>`?
In this tutorial, we used `RwLock<>` to synchronize access to the `Vec` of notifications. The main reason for using `RwLock<>` instead of `Mutex<>` is performance optimization in a concurrent environment. `RwLock<>` allows multiple readers to access the data simultaneously while ensuring that only one writer can modify the data at any given time. This is useful in scenarios where reads are more frequent than writes, as it prevents unnecessary blocking. If we had used `Mutex<>`, every read operation would require exclusive access to the lock, blocking other readers and leading to performance bottlenecks. With `RwLock<>`, multiple threads can read the notifications concurrently without interfering with each other, while still maintaining exclusive access when modifications are necessary.
### 2. Why does Rust not allow mutating the content of a static variable like in Java?
In Java, static variables are stored in a shared memory space, and their contents can be modified freely through static functions. Rust, however, enforces strict ownership and borrowing rules to prevent data races and ensure memory safety at compile time. A `static` variable in Rust has a fixed memory location and must be immutable unless explicitly wrapped in synchronization primitives like `Mutex<>` or `RwLock<>`. The reason for this restriction is that, in a multi-threaded environment, direct mutation of a static variable without synchronization could lead to undefined behavior, such as data races. Rust’s approach forces developers to explicitly handle synchronization, ensuring thread safety and memory correctness. This design makes Rust safer by preventing unintended modifications and enforcing concurrency safety at the language level.
#### Reflection Subscriber-2
pub mod subscriber;
pub mod notification;
\ No newline at end of file
use std::fmt::{Display, Formatter, Result};
use rocket::serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(crate = "rocket::serde")]
pub struct Notification {
pub product_title: String,
pub product_url: String,
pub product_type: String,
pub subscriber_name: String,
pub status: String
}
impl Display for Notification {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
if self.status.to_uppercase().eq("CREATED") {
return write!(f,
"Hello {}, let's try our new {} product: {}, only in BambangShop! Check it out: {}",
self.subscriber_name, self.product_type.to_lowercase(), self.product_title, self.product_url);
} else if self.status.to_uppercase().eq("DELETED") {
return write!(f,
"Hello {}, we informed that our {} product called {} already sold out...",
self.subscriber_name, self.product_type.to_lowercase(), self.product_title);
} else {
return write!(f,
"Hello {}, let's try our {} product: {}, grab it out before the stock ran out! Check it out: {}",
self.subscriber_name, self.product_type.to_lowercase(), self.product_title, self.product_url);
}
}
}
use rocket::serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(crate = "rocket::serde")]
pub struct SubscriberRequest {
pub url: String,
pub name: String,
}
pub mod notification;
\ No newline at end of file
use std::sync::RwLock;
use lazy_static::lazy_static;
use crate::model::notification::Notification;
// Singleton of Database
lazy_static! {
static ref NOTIFICATIONS: RwLock<Vec<Notification>> = RwLock::new(vec![]);
}
pub struct NotificationRepository;
impl NotificationRepository {
pub fn add(notification: Notification) -> Notification {
NOTIFICATIONS.write().unwrap()
.push(notification.clone());
return notification;
}
pub fn list_all_as_string() -> Vec<String> {
return NOTIFICATIONS.read().unwrap()
.iter().map(|f| format!("{}", f.clone())).collect();
}
}
\ No newline at end of file