deduplicate serve code with hot reloading in the CLI crate
This commit is contained in:
1 parent
c8127e164b
commit
49a127b31e
5 files changed
+153
-296
No files matched your search
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
server::{
|
||||
output::{print_console_info, PrettierOptions},
|
||||
setup_file_watcher, setup_file_watcher_hot_reload,
|
||||
setup_file_watcher,
|
||||
},
|
||||
BuildResult, CrateConfig, Result,
|
||||
};
|
||||
@@ -19,6 +19,8 @@ use tokio::sync::broadcast::{self};
|
||||
#[cfg(feature = "plugin")]
|
||||
use plugin::PluginManager;
|
||||
|
||||
use super::HotReloadState;
|
||||
|
||||
pub async fn startup(config: CrateConfig) -> Result<()> {
|
||||
// ctrl-c shutdown checker
|
||||
let _crate_config = config.clone();
|
||||
@@ -28,16 +30,36 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
|
||||
std::process::exit(0);
|
||||
});
|
||||
|
||||
match config.hot_reload {
|
||||
true => serve_hot_reload(config).await?,
|
||||
false => serve_default(config).await?,
|
||||
}
|
||||
let hot_reload_state = match config.hot_reload {
|
||||
true => {
|
||||
let FileMapBuildResult { map, errors } =
|
||||
FileMap::<HtmlCtx>::create(config.crate_dir.clone()).unwrap();
|
||||
|
||||
for err in errors {
|
||||
log::error!("{}", err);
|
||||
}
|
||||
|
||||
let file_map = Arc::new(Mutex::new(map));
|
||||
|
||||
let hot_reload_tx = broadcast::channel(100).0;
|
||||
|
||||
clear_paths();
|
||||
|
||||
Some(HotReloadState {
|
||||
messages: hot_reload_tx.clone(),
|
||||
file_map: file_map.clone(),
|
||||
})
|
||||
}
|
||||
false => None,
|
||||
};
|
||||
|
||||
serve(config, hot_reload_state).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Start the server without hot reload
|
||||
pub async fn serve_default(config: CrateConfig) -> Result<()> {
|
||||
pub async fn serve(config: CrateConfig, hot_reload_state: Option<HotReloadState>) -> Result<()> {
|
||||
let (child, first_build_result) = start_desktop(&config)?;
|
||||
let currently_running_child: RwLock<Child> = RwLock::new(child);
|
||||
|
||||
@@ -59,6 +81,7 @@ pub async fn serve_default(config: CrateConfig) -> Result<()> {
|
||||
},
|
||||
&config,
|
||||
None,
|
||||
hot_reload_state.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -73,79 +96,29 @@ pub async fn serve_default(config: CrateConfig) -> Result<()> {
|
||||
None,
|
||||
);
|
||||
|
||||
std::future::pending::<()>().await;
|
||||
match hot_reload_state {
|
||||
Some(hot_reload_state) => {
|
||||
start_desktop_hot_reload(hot_reload_state).await?;
|
||||
}
|
||||
None => {
|
||||
std::future::pending::<()>().await;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Start the server without hot reload
|
||||
|
||||
/// Start dx serve with hot reload
|
||||
pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
|
||||
let (_, first_build_result) = start_desktop(&config)?;
|
||||
|
||||
println!("🚀 Starting development server...");
|
||||
|
||||
// Setup hot reload
|
||||
let FileMapBuildResult { map, errors } =
|
||||
FileMap::<HtmlCtx>::create(config.crate_dir.clone()).unwrap();
|
||||
|
||||
println!("🚀 Starting development server...");
|
||||
|
||||
for err in errors {
|
||||
log::error!("{}", err);
|
||||
}
|
||||
|
||||
let file_map = Arc::new(Mutex::new(map));
|
||||
|
||||
let (hot_reload_tx, mut hot_reload_rx) = broadcast::channel(100);
|
||||
|
||||
// States
|
||||
// The open interprocess sockets
|
||||
let channels = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
// Setup file watcher
|
||||
// We got to own watcher so that it exists for the duration of serve
|
||||
// Otherwise hot reload won't work.
|
||||
let _watcher = setup_file_watcher_hot_reload(
|
||||
&config,
|
||||
hot_reload_tx,
|
||||
file_map.clone(),
|
||||
{
|
||||
let config = config.clone();
|
||||
|
||||
let channels = channels.clone();
|
||||
move || {
|
||||
for channel in &mut *channels.lock().unwrap() {
|
||||
send_msg(HotReloadMsg::Shutdown, channel);
|
||||
}
|
||||
Ok(start_desktop(&config)?.1)
|
||||
}
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Print serve info
|
||||
print_console_info(
|
||||
&config,
|
||||
PrettierOptions {
|
||||
changed: vec![],
|
||||
warnings: first_build_result.warnings,
|
||||
elapsed_time: first_build_result.elapsed_time,
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
||||
clear_paths();
|
||||
|
||||
async fn start_desktop_hot_reload(hot_reload_state: HotReloadState) -> Result<()> {
|
||||
match LocalSocketListener::bind("@dioxusin") {
|
||||
Ok(local_socket_stream) => {
|
||||
let aborted = Arc::new(Mutex::new(false));
|
||||
// States
|
||||
// The open interprocess sockets
|
||||
let channels = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
// listen for connections
|
||||
std::thread::spawn({
|
||||
let file_map = file_map.clone();
|
||||
let file_map = hot_reload_state.file_map.clone();
|
||||
let channels = channels.clone();
|
||||
let aborted = aborted.clone();
|
||||
let _ = local_socket_stream.set_nonblocking(true);
|
||||
@@ -180,6 +153,8 @@ pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
|
||||
}
|
||||
});
|
||||
|
||||
let mut hot_reload_rx = hot_reload_state.messages.subscribe();
|
||||
|
||||
while let Ok(template) = hot_reload_rx.recv().await {
|
||||
let channels = &mut *channels.lock().unwrap();
|
||||
let mut i = 0;
|
||||
|
||||
Reference in new issue
Block a user