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