Skip to content

Commit

Permalink
[ISSUE #1125]🔊Implementing functionality similar to Java's LinkedBloc…
Browse files Browse the repository at this point in the history
…kingQueue in Rust using Tokio🚀 (#1126)
  • Loading branch information
mxsm authored Nov 9, 2024
1 parent fac3627 commit 0f6030f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
73 changes: 73 additions & 0 deletions rocketmq/src/blocking_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use std::collections::VecDeque;

use tokio::sync::Mutex;
use tokio::sync::Notify;
use tokio::time;

pub struct BlockingQueue<T> {
queue: Mutex<VecDeque<T>>,
capacity: usize,
notify: Notify,
}

impl<T> BlockingQueue<T> {
pub fn new(capacity: usize) -> Self {
BlockingQueue {
queue: Mutex::new(VecDeque::with_capacity(capacity)),
capacity,
notify: Notify::new(),
}
}

pub async fn put(&self, item: T) {
loop {
{
let mut queue = self.queue.lock().await;
if queue.len() < self.capacity {
queue.push_back(item);
self.notify.notify_one(); // Notify only after successful push
return;
}
}
self.notify.notified().await;
}
}

pub async fn offer(&self, item: T, timeout: std::time::Duration) -> bool {
time::timeout(timeout, self.put(item)).await.is_ok()
}

pub async fn take(&self) -> T {
loop {
{
let mut queue = self.queue.lock().await;
if let Some(item) = queue.pop_front() {
self.notify.notify_one(); // Notify only after successful pop
return item;
}
}
self.notify.notified().await;
}
}

pub async fn poll(&self, timeout: std::time::Duration) -> Option<T> {
time::timeout(timeout, self.take()).await.ok()
}
}
2 changes: 2 additions & 0 deletions rocketmq/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
#![feature(sync_unsafe_cell)]

mod arc_mut;
mod blocking_queue;
pub mod count_down_latch;
pub mod rocketmq_tokio_lock;
mod shutdown;

pub use arc_mut::ArcMut;
pub use arc_mut::SyncUnsafeCellWrapper;
pub use arc_mut::WeakArcMut;
pub use blocking_queue::BlockingQueue as RocketMQBlockingQueue;
pub use count_down_latch::CountDownLatch;
/// Re-export rocketmq main.
pub use rocketmq::main;
Expand Down

0 comments on commit 0f6030f

Please sign in to comment.