use std::sync::Arc;
use std::thread;
use std::thread::JoinHandle;
use crossbeam::channel;
use crossbeam::channel::{Receiver, Sender};
use crate::concurrency::Semaphore;
use crate::duplicate_detection::messages::DuplicateInvestigation;
pub struct OpenFileGuard {
request_in: Receiver<DuplicateInvestigation>,
response_out: Sender<DuplicateInvestigation>,
sem: Arc<Semaphore>,
}
impl OpenFileGuard {
pub fn new(
sem: Arc<Semaphore>,
) -> (
Self,
Sender<DuplicateInvestigation>,
Receiver<DuplicateInvestigation>,
) {
let (request_out, request_in) = channel::unbounded();
let (response_out, response_in) = channel::unbounded();
(
OpenFileGuard {
request_in,
response_out,
sem,
},
request_out,
response_in,
)
}
pub fn work(self) -> JoinHandle<::anyhow::Result<Self>> {
thread::spawn(move || {
info!("Mutex guard started");
self.work_internal()?;
info!("Mutex guard ended");
Ok(self)
})
}
fn work_internal(&self) -> ::anyhow::Result<()> {
while let Ok(investigation) = self.request_in.recv() {
let work_size = investigation.duplicate.locations.len();
debug!("Requesting {} leases", work_size);
if work_size > 512 {
self.sem.acquire(512);
} else {
self.sem.acquire(work_size);
}
debug!("Leases granted");
self.response_out.send(investigation)?;
}
Ok(())
}
}