Skip to content

Commit 9d625dd

Browse files
authored
Merge pull request #49 from oiwn/dev
Dev
2 parents 69353ab + c763fd0 commit 9d625dd

File tree

15 files changed

+633
-388
lines changed

15 files changed

+633
-388
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ tags
2222

2323
tarpaulin-report.html
2424
.DS_Store
25-
all_code.txt
25+
.code

capp-queue/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ futures-util = { version = "0.3", optional = true }
1919

2020
[dev-dependencies]
2121
dotenvy = "0.15"
22+
tokio = { version = "1.41", features = ["full", "test-util"] }
2223

2324
[features]
2425
redis = ["dep:tokio", "dep:rustis"]

capp-queue/src/backend/memory.rs

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
//! In-memory implementation of TaskStorage trait. The storage allows tasks to be
22
//! pushed to and popped from a queue, and also allows tasks to be set and
33
//! retrieved by their UUID.
4-
use crate::queue::{TaskQueue, TaskQueueError};
54
use crate::task::{Task, TaskId};
5+
use crate::{TaskQueue, TaskQueueError, TaskSerializer};
66
use async_trait::async_trait;
77
use serde::de::DeserializeOwned;
88
use serde::Serialize;
99
use std::collections::{HashMap, VecDeque};
1010
use std::marker::PhantomData;
1111
use std::sync::Mutex;
1212

13-
pub struct InMemoryTaskQueue<D> {
14-
pub hashmap: Mutex<HashMap<TaskId, String>>,
13+
pub struct InMemoryTaskQueue<D, S>
14+
where
15+
S: TaskSerializer,
16+
{
17+
pub hashmap: Mutex<HashMap<TaskId, Vec<u8>>>,
1518
pub list: Mutex<VecDeque<TaskId>>,
16-
pub dlq: Mutex<HashMap<TaskId, String>>,
17-
_marker: PhantomData<D>,
19+
pub dlq: Mutex<HashMap<TaskId, Vec<u8>>>,
20+
_marker: PhantomData<(D, S)>,
1821
}
1922

20-
impl<D> InMemoryTaskQueue<D> {
23+
impl<D, S> InMemoryTaskQueue<D, S>
24+
where
25+
S: TaskSerializer,
26+
{
2127
pub fn new() -> Self {
2228
Self {
2329
hashmap: Mutex::new(HashMap::new()),
@@ -28,14 +34,17 @@ impl<D> InMemoryTaskQueue<D> {
2834
}
2935
}
3036

31-
impl<D> Default for InMemoryTaskQueue<D> {
37+
impl<D, S> Default for InMemoryTaskQueue<D, S>
38+
where
39+
S: TaskSerializer,
40+
{
3241
fn default() -> Self {
3342
Self::new()
3443
}
3544
}
3645

3746
#[async_trait]
38-
impl<D> TaskQueue<D> for InMemoryTaskQueue<D>
47+
impl<D, S> TaskQueue<D> for InMemoryTaskQueue<D, S>
3948
where
4049
D: std::fmt::Debug
4150
+ Clone
@@ -44,6 +53,7 @@ where
4453
+ Send
4554
+ Sync
4655
+ 'static,
56+
S: TaskSerializer + Send + Sync,
4757
{
4858
async fn push(&self, task: &Task<D>) -> Result<(), TaskQueueError> {
4959
let mut list = self
@@ -55,9 +65,8 @@ where
5565
.lock()
5666
.map_err(|e| TaskQueueError::QueueError(e.to_string()))?;
5767

58-
let task_value = serde_json::to_string(task)
59-
.map_err(|e| TaskQueueError::SerdeError(e.to_string()))?;
60-
hashmap.insert(task.task_id, task_value);
68+
let task_bytes = S::serialize_task(task)?;
69+
hashmap.insert(task.task_id, task_bytes);
6170
list.push_back(task.task_id);
6271
Ok(())
6372
}
@@ -73,12 +82,10 @@ where
7382
.map_err(|e| TaskQueueError::QueueError(e.to_string()))?;
7483

7584
if let Some(task_id) = list.pop_front() {
76-
let task_value = hashmap
85+
let task_bytes = hashmap
7786
.get(&task_id)
7887
.ok_or(TaskQueueError::TaskNotFound(task_id))?;
79-
let task: Task<D> = serde_json::from_str(task_value)
80-
.map_err(|e| TaskQueueError::SerdeError(e.to_string()))?;
81-
Ok(task)
88+
S::deserialize_task(task_bytes)
8289
} else {
8390
Err(TaskQueueError::QueueEmpty)
8491
}
@@ -100,9 +107,8 @@ where
100107
.dlq
101108
.lock()
102109
.map_err(|e| TaskQueueError::QueueError(e.to_string()))?;
103-
let task_value = serde_json::to_string(task)
104-
.map_err(|e| TaskQueueError::SerdeError(e.to_string()))?;
105-
dlq.insert(task.task_id, task_value);
110+
let task_bytes = S::serialize_task(task)?;
111+
dlq.insert(task.task_id, task_bytes);
106112

107113
let mut hashmap = self
108114
.hashmap
@@ -111,7 +117,6 @@ where
111117
hashmap
112118
.remove(&task.task_id)
113119
.ok_or(TaskQueueError::TaskNotFound(task.task_id))?;
114-
115120
Ok(())
116121
}
117122

@@ -120,29 +125,33 @@ where
120125
.hashmap
121126
.lock()
122127
.map_err(|e| TaskQueueError::QueueError(e.to_string()))?;
123-
let task_value = serde_json::to_string(task)
124-
.map_err(|e| TaskQueueError::SerdeError(e.to_string()))?;
125-
hashmap.insert(task.task_id, task_value);
128+
let task_bytes = S::serialize_task(task)?;
129+
hashmap.insert(task.task_id, task_bytes);
126130
Ok(())
127131
}
128132
}
129133

130-
impl<D> std::fmt::Debug for InMemoryTaskQueue<D> {
134+
impl<D, S> std::fmt::Debug for InMemoryTaskQueue<D, S>
135+
where
136+
S: TaskSerializer,
137+
{
131138
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132139
let hashmap = self.hashmap.lock().unwrap();
133140
let list = self.list.lock().unwrap();
134141
let dlq = self.dlq.lock().unwrap();
135142

136143
f.debug_struct("InMemoryTaskQueue")
137-
.field("hashmap", &*hashmap)
144+
.field("hashmap_size", &hashmap.len())
138145
.field("list", &*list)
139-
.field("dlq", &*dlq)
146+
.field("dlq_size", &dlq.len())
140147
.finish()
141148
}
142149
}
150+
143151
#[cfg(test)]
144152
mod tests {
145153
use super::*;
154+
use crate::JsonSerializer;
146155
use serde::{Deserialize, Serialize};
147156

148157
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@@ -152,7 +161,7 @@ mod tests {
152161

153162
#[tokio::test]
154163
async fn test_push_and_pop() {
155-
let queue = InMemoryTaskQueue::<TestData>::new();
164+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
156165
let task = Task::new(TestData { value: 42 });
157166

158167
queue.push(&task).await.unwrap();
@@ -163,7 +172,7 @@ mod tests {
163172

164173
#[tokio::test]
165174
async fn test_queue_empty() {
166-
let queue = InMemoryTaskQueue::<TestData>::new();
175+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
167176

168177
match queue.pop().await {
169178
Err(TaskQueueError::QueueEmpty) => (),
@@ -173,7 +182,7 @@ mod tests {
173182

174183
#[tokio::test]
175184
async fn test_ack() {
176-
let queue = InMemoryTaskQueue::<TestData>::new();
185+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
177186
let task = Task::new(TestData { value: 42 });
178187

179188
queue.push(&task).await.unwrap();
@@ -186,7 +195,7 @@ mod tests {
186195

187196
#[tokio::test]
188197
async fn test_nack() {
189-
let queue = InMemoryTaskQueue::<TestData>::new();
198+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
190199
let task = Task::new(TestData { value: 42 });
191200

192201
queue.push(&task).await.unwrap();
@@ -203,7 +212,7 @@ mod tests {
203212

204213
#[tokio::test]
205214
async fn test_set() {
206-
let queue = InMemoryTaskQueue::<TestData>::new();
215+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
207216
let mut task = Task::new(TestData { value: 42 });
208217

209218
queue.push(&task).await.unwrap();
@@ -218,7 +227,7 @@ mod tests {
218227

219228
#[tokio::test]
220229
async fn test_multiple_tasks() {
221-
let queue = InMemoryTaskQueue::<TestData>::new();
230+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
222231
let tasks = vec![
223232
Task::new(TestData { value: 1 }),
224233
Task::new(TestData { value: 2 }),
@@ -240,7 +249,7 @@ mod tests {
240249

241250
#[tokio::test]
242251
async fn test_task_not_found() {
243-
let queue = InMemoryTaskQueue::<TestData>::new();
252+
let queue = InMemoryTaskQueue::<TestData, JsonSerializer>::new();
244253
let non_existent_task_id = TaskId::new();
245254

246255
match queue.ack(&non_existent_task_id).await {

0 commit comments

Comments
 (0)