refactor: use shared state struct
parent
8864925e58
commit
656df06b4e
|
@ -11,43 +11,60 @@ use sea_orm::{
|
||||||
ActiveModelTrait, ColumnTrait, Condition, ConnectionTrait, DbConn, EntityTrait, JoinType,
|
ActiveModelTrait, ColumnTrait, Condition, ConnectionTrait, DbConn, EntityTrait, JoinType,
|
||||||
ModelTrait, NotSet, QueryFilter, QuerySelect, Related, RelationTrait, Set, TransactionTrait,
|
ModelTrait, NotSet, QueryFilter, QuerySelect, Related, RelationTrait, Set, TransactionTrait,
|
||||||
};
|
};
|
||||||
use tokio::{runtime, sync::mpsc::UnboundedReceiver};
|
use tokio::{
|
||||||
|
runtime,
|
||||||
|
sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
||||||
|
};
|
||||||
|
|
||||||
pub enum RepoCommand {
|
pub enum RepoCommand {
|
||||||
ParsePkg(i32, PathBuf),
|
ParsePkg(i32, PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct RepoSharedState {
|
||||||
|
repos_dir: PathBuf,
|
||||||
|
conn: DbConn,
|
||||||
|
rx: Mutex<UnboundedReceiver<RepoCommand>>,
|
||||||
|
tx: UnboundedSender<RepoCommand>,
|
||||||
|
repos: RwLock<HashMap<i32, (AtomicU32, Arc<Mutex<()>>)>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RepoSharedState {
|
||||||
|
pub fn new(
|
||||||
|
repos_dir: impl AsRef<Path>,
|
||||||
|
conn: DbConn,
|
||||||
|
repos: HashMap<i32, (AtomicU32, Arc<Mutex<()>>)>,
|
||||||
|
) -> Self {
|
||||||
|
let (tx, rx) = unbounded_channel();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
repos_dir: repos_dir.as_ref().to_path_buf(),
|
||||||
|
conn,
|
||||||
|
rx: Mutex::new(rx),
|
||||||
|
tx,
|
||||||
|
repos: RwLock::new(repos),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The actor is responsible for mutating the repositories. They receive their commands their
|
/// The actor is responsible for mutating the repositories. They receive their commands their
|
||||||
/// messages and process these commands in both a synchronous and asynchronous way.
|
/// messages and process these commands in both a synchronous and asynchronous way.
|
||||||
pub struct RepoActor {
|
pub struct RepoActor {
|
||||||
repos_dir: PathBuf,
|
|
||||||
conn: DbConn,
|
|
||||||
rt: runtime::Handle,
|
rt: runtime::Handle,
|
||||||
rx: Arc<Mutex<UnboundedReceiver<RepoCommand>>>,
|
state: Arc<RepoSharedState>,
|
||||||
repos: Arc<RwLock<HashMap<i32, (AtomicU32, Arc<Mutex<()>>)>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RepoActor {
|
impl RepoActor {
|
||||||
pub fn new(
|
pub fn new(rt: runtime::Handle, state: Arc<RepoSharedState>) -> Self {
|
||||||
repos_dir: PathBuf,
|
|
||||||
conn: DbConn,
|
|
||||||
rt: runtime::Handle,
|
|
||||||
rx: Arc<Mutex<UnboundedReceiver<RepoCommand>>>,
|
|
||||||
repos: Arc<RwLock<HashMap<i32, (AtomicU32, Arc<Mutex<()>>)>>>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
repos_dir,
|
|
||||||
conn,
|
|
||||||
rt,
|
rt,
|
||||||
rx,
|
state: Arc::clone(&state),
|
||||||
repos,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the main actor loop
|
/// Run the main actor loop
|
||||||
pub fn run(self) {
|
pub fn run(self) {
|
||||||
while let Some(msg) = {
|
while let Some(msg) = {
|
||||||
let mut rx = self.rx.lock().unwrap();
|
let mut rx = self.state.rx.lock().unwrap();
|
||||||
rx.blocking_recv()
|
rx.blocking_recv()
|
||||||
} {
|
} {
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -62,8 +79,9 @@ impl RepoActor {
|
||||||
let pkg = package::Package::open(&path)?;
|
let pkg = package::Package::open(&path)?;
|
||||||
let pkg = self
|
let pkg = self
|
||||||
.rt
|
.rt
|
||||||
.block_on(db::query::package::insert(&self.conn, repo, pkg))?;
|
.block_on(db::query::package::insert(&self.state.conn, repo, pkg))?;
|
||||||
let dest_path = self
|
let dest_path = self
|
||||||
|
.state
|
||||||
.repos_dir
|
.repos_dir
|
||||||
.join(repo.to_string())
|
.join(repo.to_string())
|
||||||
.join(pkg.id.to_string());
|
.join(pkg.id.to_string());
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::RepoSharedState;
|
||||||
use crate::db;
|
use crate::db;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -17,10 +18,7 @@ use tokio::{
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RepoHandle {
|
pub struct RepoHandle {
|
||||||
repos_dir: PathBuf,
|
state: Arc<RepoSharedState>,
|
||||||
conn: DbConn,
|
|
||||||
tx: UnboundedSender<super::RepoCommand>,
|
|
||||||
repos: Arc<RwLock<HashMap<i32, (AtomicU32, Arc<Mutex<()>>)>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RepoHandle {
|
impl RepoHandle {
|
||||||
|
@ -32,8 +30,6 @@ impl RepoHandle {
|
||||||
) -> crate::Result<Self> {
|
) -> crate::Result<Self> {
|
||||||
std::fs::create_dir_all(repos_dir.as_ref())?;
|
std::fs::create_dir_all(repos_dir.as_ref())?;
|
||||||
|
|
||||||
let (tx, rx) = unbounded_channel();
|
|
||||||
|
|
||||||
let mut repos = HashMap::new();
|
let mut repos = HashMap::new();
|
||||||
let repo_ids: Vec<i32> = rt.block_on(
|
let repo_ids: Vec<i32> = rt.block_on(
|
||||||
db::Repo::find()
|
db::Repo::find()
|
||||||
|
@ -47,26 +43,14 @@ impl RepoHandle {
|
||||||
repos.insert(id, Default::default());
|
repos.insert(id, Default::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let rx = Arc::new(Mutex::new(rx));
|
let state = Arc::new(RepoSharedState::new(repos_dir, conn, repos));
|
||||||
let repos = Arc::new(RwLock::new(repos));
|
|
||||||
|
|
||||||
for _ in 0..actors {
|
for _ in 0..actors {
|
||||||
let actor = super::RepoActor::new(
|
let actor = super::RepoActor::new(rt.clone(), Arc::clone(&state));
|
||||||
repos_dir.as_ref().to_path_buf(),
|
|
||||||
conn.clone(),
|
|
||||||
rt.clone(),
|
|
||||||
Arc::clone(&rx),
|
|
||||||
Arc::clone(&repos),
|
|
||||||
);
|
|
||||||
|
|
||||||
std::thread::spawn(|| actor.run());
|
std::thread::spawn(|| actor.run());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { state })
|
||||||
repos_dir: repos_dir.as_ref().to_path_buf(),
|
|
||||||
conn,
|
|
||||||
tx,
|
|
||||||
repos,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ mod handle;
|
||||||
mod manager;
|
mod manager;
|
||||||
pub mod package;
|
pub mod package;
|
||||||
|
|
||||||
pub use actor::{RepoActor, RepoCommand};
|
pub use actor::{RepoActor, RepoCommand, RepoSharedState};
|
||||||
pub use handle::RepoHandle;
|
pub use handle::RepoHandle;
|
||||||
pub use manager::RepoMgr;
|
pub use manager::RepoMgr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue