use super::{JobBackend, JobRequest};
use crate::error::{JobError, Result};
use async_trait::async_trait;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
#[derive(Debug, Clone, Default)]
pub struct InMemoryBackend {
queue: Arc<Mutex<VecDeque<JobRequest>>>,
}
impl InMemoryBackend {
pub fn new() -> Self {
Self::default()
}
}
#[async_trait]
impl JobBackend for InMemoryBackend {
async fn push(&self, job: JobRequest) -> Result<()> {
let mut q = self
.queue
.lock()
.map_err(|_| JobError::BackendError("Lock poisoned".to_string()))?;
q.push_back(job);
Ok(())
}
async fn pop(&self) -> Result<Option<JobRequest>> {
let mut q = self
.queue
.lock()
.map_err(|_| JobError::BackendError("Lock poisoned".to_string()))?;
let now = chrono::Utc::now();
let mut index_to_remove = None;
for (i, job) in q.iter().enumerate() {
if let Some(run_at) = job.run_at {
if run_at > now {
continue;
}
}
index_to_remove = Some(i);
break;
}
if let Some(i) = index_to_remove {
Ok(q.remove(i))
} else {
Ok(None)
}
}
async fn complete(&self, _job_id: &str) -> Result<()> {
Ok(())
}
async fn fail(&self, _job_id: &str, _error: &str) -> Result<()> {
Ok(())
}
}