-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5578c93
commit 421e9aa
Showing
8 changed files
with
215 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
use std::sync::{Arc, RwLock}; | ||
|
||
use media_server_utils::now_ms; | ||
|
||
use super::events::HookEvent; | ||
|
||
#[derive(Clone)] | ||
pub struct HookJobData { | ||
pub payload: HookEvent, | ||
pub ts: u64, | ||
on_done: Arc<dyn Fn(String)>, | ||
} | ||
|
||
impl HookJobData { | ||
pub fn ack(&self) { | ||
(self.on_done)(self.payload.id().to_string()); | ||
} | ||
} | ||
|
||
pub trait HookStorage { | ||
fn push_back(&self, data: HookEvent); | ||
fn jobs(&self, limit: i16) -> Vec<HookJobData>; | ||
fn clean_timeout_event(&self, now: u64); | ||
} | ||
|
||
pub struct InMemoryHookStorage { | ||
queue: Arc<RwLock<Vec<HookJobData>>>, | ||
} | ||
|
||
impl InMemoryHookStorage { | ||
pub fn default() -> Self { | ||
Self { queue: Default::default() } | ||
} | ||
|
||
pub fn len(&self) -> usize { | ||
self.queue.read().unwrap().len() | ||
} | ||
} | ||
|
||
impl HookStorage for InMemoryHookStorage { | ||
fn push_back(&self, data: HookEvent) { | ||
let cloned_queue = self.queue.clone(); | ||
let ack = move |uuid: String| { | ||
let mut queue = cloned_queue.write().unwrap(); | ||
queue.retain(|job| job.payload.id() != uuid.as_str()); | ||
}; | ||
let ack = Arc::new(ack); | ||
let mut queue = self.queue.write().unwrap(); | ||
queue.push(HookJobData { | ||
payload: data, | ||
ts: now_ms(), | ||
on_done: ack, | ||
}); | ||
} | ||
|
||
fn jobs(&self, limit: i16) -> Vec<HookJobData> { | ||
let queue = self.queue.read().unwrap(); | ||
let mut jobs = Vec::new(); | ||
for job in queue.iter() { | ||
jobs.push(job.clone()); | ||
if jobs.len() as i16 >= limit { | ||
break; | ||
} | ||
} | ||
jobs | ||
} | ||
|
||
fn clean_timeout_event(&self, now: u64) { | ||
let mut queue = self.queue.write().unwrap(); | ||
queue.retain(|job| now - job.ts < 5000); | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_in_memory_hook_storage() { | ||
let storage = InMemoryHookStorage::default(); | ||
// let cloned = storage.clone(); | ||
|
||
for i in 0..10 { | ||
let event = HookEvent::Peer { | ||
uuid: i.to_string(), | ||
node: 1, | ||
ts: i, | ||
session: 1, | ||
room: "a".to_string(), | ||
peer: "a".to_string(), | ||
event: crate::hooks::events::PeerEvent::Joined, | ||
}; | ||
storage.push_back(event); | ||
} | ||
|
||
let jobs = storage.jobs(2); | ||
let job_ids = jobs.iter().map(|job| job.payload.id()).collect::<Vec<&str>>(); | ||
assert_eq!(job_ids, vec!["0", "1"]); | ||
|
||
let first_job = jobs.first().unwrap(); | ||
first_job.ack(); | ||
assert_eq!(storage.len(), 9); | ||
|
||
let jobs = storage.jobs(2); | ||
let job_ids = jobs.iter().map(|job| job.payload.id()).collect::<Vec<&str>>(); | ||
assert_eq!(job_ids, vec!["1", "2"]); | ||
|
||
storage.clean_timeout_event(now_ms()); | ||
assert_eq!(storage.len(), 9); | ||
|
||
storage.clean_timeout_event(now_ms() + 5000); | ||
assert_eq!(storage.len(), 0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
use std::{collections::VecDeque, sync::Arc}; | ||
|
||
use super::{storage::HookJobData, HookPublisher}; | ||
|
||
pub struct HookWorker { | ||
queues: VecDeque<HookJobData>, | ||
publisher: Option<Arc<dyn HookPublisher>>, | ||
} | ||
|
||
impl HookWorker { | ||
pub fn new(publisher: Option<Arc<dyn HookPublisher>>) -> Self { | ||
Self { queues: VecDeque::new(), publisher } | ||
} | ||
|
||
pub fn push(&mut self, data: HookJobData) { | ||
self.queues.push_back(data); | ||
} | ||
|
||
pub async fn on_tick(&mut self) { | ||
while let Some(job) = self.queues.pop_front() { | ||
if let Some(publisher) = &self.publisher { | ||
let err = publisher.publish(job.payload.clone()).await; | ||
if err.is_some() { | ||
log::error!("[HookWorker] Failed to publish hook event: {:?}", err); | ||
continue; | ||
} | ||
} | ||
job.ack(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters