mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 23:59:48 +00:00
Refactored the runtime API handling
This commit is contained in:
parent
f03ca4e8f8
commit
e6789dcfeb
@ -13,6 +13,7 @@ use crate::certificate::CERTIFICATE_FINGERPRINT;
|
|||||||
use crate::encryption::ENCRYPTION;
|
use crate::encryption::ENCRYPTION;
|
||||||
use crate::environment::is_dev;
|
use crate::environment::is_dev;
|
||||||
use crate::network::get_available_port;
|
use crate::network::get_available_port;
|
||||||
|
use crate::runtime_api::API_SERVER_PORT;
|
||||||
|
|
||||||
// The .NET server is started in a separate process and communicates with this
|
// The .NET server is started in a separate process and communicates with this
|
||||||
// runtime process via IPC. However, we do net start the .NET server in
|
// runtime process via IPC. However, we do net start the .NET server in
|
||||||
@ -31,7 +32,7 @@ pub fn dotnet_port(_token: APIToken) -> String {
|
|||||||
format!("{dotnet_server_port}")
|
format!("{dotnet_server_port}")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_dotnet_server(api_server_port: u16) {
|
pub fn start_dotnet_server() {
|
||||||
|
|
||||||
// Get the secret password & salt and convert it to a base64 string:
|
// Get the secret password & salt and convert it to a base64 string:
|
||||||
let secret_password = BASE64_STANDARD.encode(ENCRYPTION.secret_password);
|
let secret_password = BASE64_STANDARD.encode(ENCRYPTION.secret_password);
|
||||||
@ -47,8 +48,7 @@ pub fn start_dotnet_server(api_server_port: u16) {
|
|||||||
info!("Try to start the .NET server...");
|
info!("Try to start the .NET server...");
|
||||||
let server_spawn_clone = DOTNET_SERVER.clone();
|
let server_spawn_clone = DOTNET_SERVER.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
let api_port = api_server_port;
|
let api_port = *API_SERVER_PORT;
|
||||||
|
|
||||||
let (mut rx, child) = match is_dev() {
|
let (mut rx, child) = match is_dev() {
|
||||||
true => {
|
true => {
|
||||||
// We are in the development environment, so we try to start a process
|
// We are in the development environment, so we try to start a process
|
||||||
|
@ -7,4 +7,5 @@ pub mod api_token;
|
|||||||
pub mod app_window;
|
pub mod app_window;
|
||||||
pub mod secret;
|
pub mod secret;
|
||||||
pub mod clipboard;
|
pub mod clipboard;
|
||||||
|
pub mod runtime_api;
|
||||||
pub mod certificate;
|
pub mod certificate;
|
@ -4,31 +4,13 @@
|
|||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
|
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rocket::figment::Figment;
|
|
||||||
use rocket::routes;
|
|
||||||
use rocket::config::{Shutdown};
|
|
||||||
use mindwork_ai_studio::app_window::start_tauri;
|
use mindwork_ai_studio::app_window::start_tauri;
|
||||||
use mindwork_ai_studio::certificate::{generate_certificate, CERTIFICATE, CERTIFICATE_PRIVATE_KEY};
|
use mindwork_ai_studio::certificate::{generate_certificate};
|
||||||
use mindwork_ai_studio::dotnet::start_dotnet_server;
|
use mindwork_ai_studio::dotnet::start_dotnet_server;
|
||||||
use mindwork_ai_studio::environment::is_dev;
|
use mindwork_ai_studio::environment::is_dev;
|
||||||
use mindwork_ai_studio::log::init_logging;
|
use mindwork_ai_studio::log::init_logging;
|
||||||
use mindwork_ai_studio::network::get_available_port;
|
use mindwork_ai_studio::runtime_api::start_runtime_api;
|
||||||
|
|
||||||
// The port used for the runtime API server. In the development environment, we use a fixed
|
|
||||||
// port, in the production environment we use the next available port. This differentiation
|
|
||||||
// is necessary because we cannot communicate the port to the .NET server in the development
|
|
||||||
// environment.
|
|
||||||
static API_SERVER_PORT: Lazy<u16> = Lazy::new(|| {
|
|
||||||
if is_dev() {
|
|
||||||
5000
|
|
||||||
} else {
|
|
||||||
get_available_port().unwrap()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
@ -48,6 +30,7 @@ async fn main() {
|
|||||||
init_logging();
|
init_logging();
|
||||||
|
|
||||||
info!("Starting MindWork AI Studio:");
|
info!("Starting MindWork AI Studio:");
|
||||||
|
|
||||||
let working_directory = std::env::current_dir().unwrap();
|
let working_directory = std::env::current_dir().unwrap();
|
||||||
info!(".. The working directory is: '{working_directory:?}'");
|
info!(".. The working directory is: '{working_directory:?}'");
|
||||||
|
|
||||||
@ -66,78 +49,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generate_certificate();
|
generate_certificate();
|
||||||
|
start_runtime_api();
|
||||||
let api_port = *API_SERVER_PORT;
|
start_dotnet_server();
|
||||||
info!("Try to start the API server on 'http://localhost:{api_port}'...");
|
|
||||||
|
|
||||||
// The shutdown configuration for the runtime API server:
|
|
||||||
let mut shutdown = Shutdown {
|
|
||||||
// We do not want to use the Ctrl+C signal to stop the server:
|
|
||||||
ctrlc: false,
|
|
||||||
|
|
||||||
// Everything else is set to default for now:
|
|
||||||
..Shutdown::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
// We do not want to use the termination signal to stop the server.
|
|
||||||
// This option, however, is only available on Unix systems:
|
|
||||||
shutdown.signals = HashSet::new();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure the runtime API server:
|
|
||||||
let figment = Figment::from(rocket::Config::release_default())
|
|
||||||
|
|
||||||
// We use the next available port which was determined before:
|
|
||||||
.merge(("port", api_port))
|
|
||||||
|
|
||||||
// The runtime API server should be accessible only from the local machine:
|
|
||||||
.merge(("address", "127.0.0.1"))
|
|
||||||
|
|
||||||
// We do not want to use the Ctrl+C signal to stop the server:
|
|
||||||
.merge(("ctrlc", false))
|
|
||||||
|
|
||||||
// Set a name for the server:
|
|
||||||
.merge(("ident", "AI Studio Runtime API"))
|
|
||||||
|
|
||||||
// Set the maximum number of workers and blocking threads:
|
|
||||||
.merge(("workers", 3))
|
|
||||||
.merge(("max_blocking", 12))
|
|
||||||
|
|
||||||
// No colors and emojis in the log output:
|
|
||||||
.merge(("cli_colors", false))
|
|
||||||
|
|
||||||
// Read the TLS certificate and key from the generated certificate data in-memory:
|
|
||||||
.merge(("tls.certs", CERTIFICATE.get().unwrap()))
|
|
||||||
.merge(("tls.key", CERTIFICATE_PRIVATE_KEY.get().unwrap()))
|
|
||||||
|
|
||||||
// Set the shutdown configuration:
|
|
||||||
.merge(("shutdown", shutdown));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Start the runtime API server in a separate thread. This is necessary
|
|
||||||
// because the server is blocking, and we need to run the Tauri app in
|
|
||||||
// parallel:
|
|
||||||
//
|
|
||||||
tauri::async_runtime::spawn(async move {
|
|
||||||
rocket::custom(figment)
|
|
||||||
.mount("/", routes![
|
|
||||||
mindwork_ai_studio::dotnet::dotnet_port,
|
|
||||||
mindwork_ai_studio::dotnet::dotnet_ready,
|
|
||||||
mindwork_ai_studio::clipboard::set_clipboard,
|
|
||||||
mindwork_ai_studio::app_window::check_for_update,
|
|
||||||
mindwork_ai_studio::app_window::install_update,
|
|
||||||
mindwork_ai_studio::secret::get_secret,
|
|
||||||
mindwork_ai_studio::secret::store_secret,
|
|
||||||
mindwork_ai_studio::secret::delete_secret,
|
|
||||||
mindwork_ai_studio::environment::get_data_directory,
|
|
||||||
mindwork_ai_studio::environment::get_config_directory,
|
|
||||||
])
|
|
||||||
.ignite().await.unwrap()
|
|
||||||
.launch().await.unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
start_dotnet_server(*API_SERVER_PORT);
|
|
||||||
start_tauri();
|
start_tauri();
|
||||||
}
|
}
|
94
runtime/src/runtime_api.rs
Normal file
94
runtime/src/runtime_api.rs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
use log::info;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rocket::config::Shutdown;
|
||||||
|
use rocket::figment::Figment;
|
||||||
|
use rocket::routes;
|
||||||
|
use crate::certificate::{CERTIFICATE, CERTIFICATE_PRIVATE_KEY};
|
||||||
|
use crate::environment::is_dev;
|
||||||
|
use crate::network::get_available_port;
|
||||||
|
|
||||||
|
// The port used for the runtime API server. In the development environment, we use a fixed
|
||||||
|
// port, in the production environment we use the next available port. This differentiation
|
||||||
|
// is necessary because we cannot communicate the port to the .NET server in the development
|
||||||
|
// environment.
|
||||||
|
pub static API_SERVER_PORT: Lazy<u16> = Lazy::new(|| {
|
||||||
|
if is_dev() {
|
||||||
|
5000
|
||||||
|
} else {
|
||||||
|
get_available_port().unwrap()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn start_runtime_api() {
|
||||||
|
let api_port = *API_SERVER_PORT;
|
||||||
|
info!("Try to start the API server on 'http://localhost:{api_port}'...");
|
||||||
|
|
||||||
|
// The shutdown configuration for the runtime API server:
|
||||||
|
let mut shutdown = Shutdown {
|
||||||
|
// We do not want to use the Ctrl+C signal to stop the server:
|
||||||
|
ctrlc: false,
|
||||||
|
|
||||||
|
// Everything else is set to default for now:
|
||||||
|
..Shutdown::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
// We do not want to use the termination signal to stop the server.
|
||||||
|
// This option, however, is only available on Unix systems:
|
||||||
|
shutdown.signals = HashSet::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the runtime API server:
|
||||||
|
let figment = Figment::from(rocket::Config::release_default())
|
||||||
|
|
||||||
|
// We use the next available port which was determined before:
|
||||||
|
.merge(("port", api_port))
|
||||||
|
|
||||||
|
// The runtime API server should be accessible only from the local machine:
|
||||||
|
.merge(("address", "127.0.0.1"))
|
||||||
|
|
||||||
|
// We do not want to use the Ctrl+C signal to stop the server:
|
||||||
|
.merge(("ctrlc", false))
|
||||||
|
|
||||||
|
// Set a name for the server:
|
||||||
|
.merge(("ident", "AI Studio Runtime API"))
|
||||||
|
|
||||||
|
// Set the maximum number of workers and blocking threads:
|
||||||
|
.merge(("workers", 3))
|
||||||
|
.merge(("max_blocking", 12))
|
||||||
|
|
||||||
|
// No colors and emojis in the log output:
|
||||||
|
.merge(("cli_colors", false))
|
||||||
|
|
||||||
|
// Read the TLS certificate and key from the generated certificate data in-memory:
|
||||||
|
.merge(("tls.certs", CERTIFICATE.get().unwrap()))
|
||||||
|
.merge(("tls.key", CERTIFICATE_PRIVATE_KEY.get().unwrap()))
|
||||||
|
|
||||||
|
// Set the shutdown configuration:
|
||||||
|
.merge(("shutdown", shutdown));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start the runtime API server in a separate thread. This is necessary
|
||||||
|
// because the server is blocking, and we need to run the Tauri app in
|
||||||
|
// parallel:
|
||||||
|
//
|
||||||
|
tauri::async_runtime::spawn(async move {
|
||||||
|
rocket::custom(figment)
|
||||||
|
.mount("/", routes![
|
||||||
|
crate::dotnet::dotnet_port,
|
||||||
|
crate::dotnet::dotnet_ready,
|
||||||
|
crate::clipboard::set_clipboard,
|
||||||
|
crate::app_window::check_for_update,
|
||||||
|
crate::app_window::install_update,
|
||||||
|
crate::secret::get_secret,
|
||||||
|
crate::secret::store_secret,
|
||||||
|
crate::secret::delete_secret,
|
||||||
|
crate::environment::get_data_directory,
|
||||||
|
crate::environment::get_config_directory,
|
||||||
|
])
|
||||||
|
.ignite().await.unwrap()
|
||||||
|
.launch().await.unwrap();
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user