2021-04-22 10:14:29 +02:00
|
|
|
use std::{collections::HashSet, path::PathBuf};
|
2021-03-23 11:00:50 +01:00
|
|
|
|
|
|
|
use log::{info, warn};
|
|
|
|
use tokio::sync::mpsc;
|
|
|
|
use uuid::Uuid;
|
|
|
|
|
2021-06-17 14:38:52 +02:00
|
|
|
use super::{error::UuidResolverError, Result, UuidResolveMsg, UuidStore};
|
2021-03-23 11:00:50 +01:00
|
|
|
|
|
|
|
pub struct UuidResolverActor<S> {
|
|
|
|
inbox: mpsc::Receiver<UuidResolveMsg>,
|
|
|
|
store: S,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<S: UuidStore> UuidResolverActor<S> {
|
|
|
|
pub fn new(inbox: mpsc::Receiver<UuidResolveMsg>, store: S) -> Self {
|
|
|
|
Self { inbox, store }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn run(mut self) {
|
|
|
|
use UuidResolveMsg::*;
|
|
|
|
|
|
|
|
info!("uuid resolver started");
|
|
|
|
|
|
|
|
loop {
|
|
|
|
match self.inbox.recv().await {
|
2021-03-25 14:21:05 +01:00
|
|
|
Some(Get { uid: name, ret }) => {
|
|
|
|
let _ = ret.send(self.handle_get(name).await);
|
2021-03-23 11:00:50 +01:00
|
|
|
}
|
|
|
|
Some(Delete { uid: name, ret }) => {
|
|
|
|
let _ = ret.send(self.handle_delete(name).await);
|
|
|
|
}
|
|
|
|
Some(List { ret }) => {
|
|
|
|
let _ = ret.send(self.handle_list().await);
|
|
|
|
}
|
2021-03-25 14:21:05 +01:00
|
|
|
Some(Insert { ret, uuid, name }) => {
|
|
|
|
let _ = ret.send(self.handle_insert(name, uuid).await);
|
|
|
|
}
|
2021-03-23 11:00:50 +01:00
|
|
|
Some(SnapshotRequest { path, ret }) => {
|
|
|
|
let _ = ret.send(self.handle_snapshot(path).await);
|
|
|
|
}
|
2021-04-09 14:41:24 +02:00
|
|
|
Some(GetSize { ret }) => {
|
|
|
|
let _ = ret.send(self.handle_get_size().await);
|
|
|
|
}
|
2021-05-24 16:05:43 +02:00
|
|
|
Some(DumpRequest { path, ret }) => {
|
|
|
|
let _ = ret.send(self.handle_dump(path).await);
|
|
|
|
}
|
2021-03-23 11:00:50 +01:00
|
|
|
// all senders have been dropped, need to quit.
|
|
|
|
None => break,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
warn!("exiting uuid resolver loop");
|
|
|
|
}
|
|
|
|
|
2021-03-25 14:21:05 +01:00
|
|
|
async fn handle_get(&self, uid: String) -> Result<Uuid> {
|
2021-03-23 11:00:50 +01:00
|
|
|
self.store
|
|
|
|
.get_uuid(uid.clone())
|
|
|
|
.await?
|
2021-05-24 16:05:43 +02:00
|
|
|
.ok_or(UuidResolverError::UnexistingIndex(uid))
|
2021-03-23 11:00:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn handle_delete(&self, uid: String) -> Result<Uuid> {
|
|
|
|
self.store
|
|
|
|
.delete(uid.clone())
|
|
|
|
.await?
|
2021-05-24 16:05:43 +02:00
|
|
|
.ok_or(UuidResolverError::UnexistingIndex(uid))
|
2021-03-23 11:00:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn handle_list(&self) -> Result<Vec<(String, Uuid)>> {
|
|
|
|
let result = self.store.list().await?;
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
|
2021-04-22 10:14:29 +02:00
|
|
|
async fn handle_snapshot(&self, path: PathBuf) -> Result<HashSet<Uuid>> {
|
2021-03-23 11:00:50 +01:00
|
|
|
self.store.snapshot(path).await
|
|
|
|
}
|
2021-03-25 14:21:05 +01:00
|
|
|
|
2021-05-24 16:05:43 +02:00
|
|
|
async fn handle_dump(&self, path: PathBuf) -> Result<HashSet<Uuid>> {
|
|
|
|
self.store.dump(path).await
|
|
|
|
}
|
|
|
|
|
2021-03-25 14:21:05 +01:00
|
|
|
async fn handle_insert(&self, uid: String, uuid: Uuid) -> Result<()> {
|
|
|
|
if !is_index_uid_valid(&uid) {
|
2021-05-24 16:05:43 +02:00
|
|
|
return Err(UuidResolverError::BadlyFormatted(uid));
|
2021-03-25 14:21:05 +01:00
|
|
|
}
|
|
|
|
self.store.insert(uid, uuid).await?;
|
|
|
|
Ok(())
|
|
|
|
}
|
2021-04-09 14:41:24 +02:00
|
|
|
|
|
|
|
async fn handle_get_size(&self) -> Result<u64> {
|
|
|
|
self.store.get_size().await
|
|
|
|
}
|
2021-03-23 11:00:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn is_index_uid_valid(uid: &str) -> bool {
|
|
|
|
uid.chars()
|
|
|
|
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
|
|
|
|
}
|