From b2c45bf5c16391917caccd703ac85b80c5c77cca Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 24 Oct 2025 14:47:20 +0800 Subject: Re-export subcrate `action_system` to `just_enough_vcs` --- crates/system_action/src/lib.rs | 5 +++-- crates/vcs_actions/src/actions/local_actions.rs | 12 +++++++++++- crates/vcs_actions/src/registry/client_registry.rs | 5 +++-- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/system_action/src/lib.rs b/crates/system_action/src/lib.rs index 07be1bb..12ae999 100644 --- a/crates/system_action/src/lib.rs +++ b/crates/system_action/src/lib.rs @@ -1,5 +1,6 @@ -pub use action_system_macros::*; -pub extern crate action_system_macros as macros; +pub mod macros { + pub use action_system_macros::*; +} pub mod action; pub mod action_pool; diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs index b11a934..55d014e 100644 --- a/crates/vcs_actions/src/actions/local_actions.rs +++ b/crates/vcs_actions/src/actions/local_actions.rs @@ -1,4 +1,6 @@ -use action_system::{action::ActionContext, action_gen}; +use std::net::SocketAddr; + +use action_system::{action::ActionContext, macros::action_gen}; use log::info; use tcp_connection::error::TcpTargetError; @@ -23,3 +25,11 @@ pub async fn hello_world_action(ctx: ActionContext, _n: ()) -> Result<(), TcpTar Ok(()) } + +#[action_gen] +pub async fn set_upstream_vault_action( + ctx: ActionContext, + upstream: SocketAddr, +) -> Result<(), TcpTargetError> { + Ok(()) +} diff --git a/crates/vcs_actions/src/registry/client_registry.rs b/crates/vcs_actions/src/registry/client_registry.rs index 5939bed..484c4f4 100644 --- a/crates/vcs_actions/src/registry/client_registry.rs +++ b/crates/vcs_actions/src/registry/client_registry.rs @@ -2,12 +2,13 @@ use action_system::{action::ActionContext, action_pool::ActionPool}; use tcp_connection::error::TcpTargetError; use crate::{ - actions::local_actions::register_hello_world_action, connection::protocol::RemoteActionInvoke, + actions::local_actions::register_set_upstream_vault_action, + connection::protocol::RemoteActionInvoke, }; fn register_actions(pool: &mut ActionPool) { // Pool register here - register_hello_world_action(pool); + register_set_upstream_vault_action(pool); } pub fn client_action_pool() -> ActionPool { -- cgit From ac71a819dd45090a2ee1054208fd027f05a8c36c Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Fri, 24 Oct 2025 18:24:04 +0800 Subject: Fix some spelling issues. --- crates/vcs_actions/src/actions/local_actions.rs | 19 ++++++++++++++++++- crates/vcs_actions/src/registry/server_registry.rs | 4 ++-- crates/vcs_data/src/data/local.rs | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) (limited to 'crates') diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs index 55d014e..c19b8f0 100644 --- a/crates/vcs_actions/src/actions/local_actions.rs +++ b/crates/vcs_actions/src/actions/local_actions.rs @@ -29,7 +29,24 @@ pub async fn hello_world_action(ctx: ActionContext, _n: ()) -> Result<(), TcpTar #[action_gen] pub async fn set_upstream_vault_action( ctx: ActionContext, - upstream: SocketAddr, + _upstream: SocketAddr, ) -> Result<(), TcpTargetError> { + // Ensure the instance is available + let Some(instance) = ctx.instance() else { + return Err(TcpTargetError::NotFound( + "Connection Instance Lost.".to_string(), + )); + }; + + if ctx.is_local() { + // Invoke on local + // Send the message to the server + let _ = instance.lock().await.write_text("Hello World!").await; + } else if ctx.is_remote() { + // Read the message from the client + let read = instance.lock().await.read_text().await?; + info!("{}", read) + } + Ok(()) } diff --git a/crates/vcs_actions/src/registry/server_registry.rs b/crates/vcs_actions/src/registry/server_registry.rs index b449b68..3ecc103 100644 --- a/crates/vcs_actions/src/registry/server_registry.rs +++ b/crates/vcs_actions/src/registry/server_registry.rs @@ -1,9 +1,9 @@ use action_system::action_pool::ActionPool; -use crate::actions::local_actions::register_hello_world_action; +use crate::actions::local_actions::register_set_upstream_vault_action; pub fn server_action_pool() -> ActionPool { let mut pool = ActionPool::new(); - register_hello_world_action(&mut pool); + register_set_upstream_vault_action(&mut pool); pool } diff --git a/crates/vcs_data/src/data/local.rs b/crates/vcs_data/src/data/local.rs index 1c99832..c93bd2b 100644 --- a/crates/vcs_data/src/data/local.rs +++ b/crates/vcs_data/src/data/local.rs @@ -93,7 +93,7 @@ Without these credentials, the server will reject all access requests. } /// Setup local workspace in current directory - pub async fn setup_local_workspacecurrent_dir() -> Result<(), std::io::Error> { + pub async fn setup_local_workspace_current_dir() -> Result<(), std::io::Error> { Self::setup_local_workspace(current_dir()?).await?; Ok(()) } -- cgit From e5238eebd2bc9cfbb508d7b69b3b84708bf184f7 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 15:23:28 +0800 Subject: Add some debug logs --- crates/vcs_actions/src/actions/local_actions.rs | 11 ++-- .../vcs_actions/src/connection/action_service.rs | 66 ++++++++++++++++++---- 2 files changed, 61 insertions(+), 16 deletions(-) (limited to 'crates') diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs index c19b8f0..c2d9f4f 100644 --- a/crates/vcs_actions/src/actions/local_actions.rs +++ b/crates/vcs_actions/src/actions/local_actions.rs @@ -14,11 +14,10 @@ pub async fn hello_world_action(ctx: ActionContext, _n: ()) -> Result<(), TcpTar }; if ctx.is_local() { - // Invoke on local - // Send the message to the server - let _ = instance.lock().await.write_text("Hello World!").await; + // Local execution - communication is handled by on_proc_begin + info!("Hello World action executed locally"); } else if ctx.is_remote() { - // Read the message from the client + // Remote execution - read the message from the client let read = instance.lock().await.read_text().await?; info!("{}", read) } @@ -43,9 +42,9 @@ pub async fn set_upstream_vault_action( // Send the message to the server let _ = instance.lock().await.write_text("Hello World!").await; } else if ctx.is_remote() { - // Read the message from the client + // Remote execution - read the message from the client let read = instance.lock().await.read_text().await?; - info!("{}", read) + info!("Received: {}", read) } Ok(()) diff --git a/crates/vcs_actions/src/connection/action_service.rs b/crates/vcs_actions/src/connection/action_service.rs index c302fd4..f76921e 100644 --- a/crates/vcs_actions/src/connection/action_service.rs +++ b/crates/vcs_actions/src/connection/action_service.rs @@ -1,7 +1,13 @@ -use std::{net::SocketAddr, path::PathBuf, sync::Arc}; +use std::{ + net::SocketAddr, + path::PathBuf, + sync::Arc, + time::{Duration, Instant}, +}; use action_system::{action::ActionContext, action_pool::ActionPool}; use cfg_file::config::ConfigFile; +use log::{error, info, warn}; use tcp_connection::{error::TcpTargetError, instance::ConnectionInstance}; use tokio::{ net::{TcpListener, TcpStream}, @@ -67,11 +73,32 @@ fn build_server_future( let mut active_connections = 0; let mut shutdown_requested = false; - // Spawn task to handle Ctrl+C + // Spawn task to handle Ctrl+C with rapid exit detection let shutdown_tx_clone = shutdown_tx.clone(); spawn(async move { - if let Ok(()) = signal::ctrl_c().await { + let mut ctrl_c_count = 0; + let mut last_ctrl_c_time = Instant::now(); + + while let Ok(()) = signal::ctrl_c().await { + let now = Instant::now(); + + // Reset counter if more than 5 seconds have passed + if now.duration_since(last_ctrl_c_time) > Duration::from_secs(5) { + ctrl_c_count = 0; + } + + ctrl_c_count += 1; + last_ctrl_c_time = now; + let _ = shutdown_tx_clone.send(()).await; + + // If 3 Ctrl+C within 5 seconds, exit immediately + if ctrl_c_count >= 3 { + info!("Shutdown. (3/3)"); + std::process::exit(0); + } else { + info!("Ctrl + C to force shutdown. ({} / 3)", ctrl_c_count); + } } }); @@ -82,14 +109,16 @@ fn build_server_future( accept_result = listener.accept(), if !shutdown_requested => { match accept_result { Ok((stream, _addr)) => { - active_connections += 1; + info!("New connection accepted."); let _ = tx.send(1).await; let vault_clone = vault.clone(); let action_pool_clone = action_pool.clone(); let tx_clone = tx.clone(); + spawn(async move { process_connection(stream, vault_clone, action_pool_clone).await; + info!("A connection closed."); let _ = tx_clone.send(-1).await; }); } @@ -114,7 +143,10 @@ fn build_server_future( shutdown_requested = true; // If no active connections, break immediately if active_connections == 0 { + info!("No active connections. Shutting down."); break; + } else { + warn!("Cannot shutdown while active connections exist! ({} active)", active_connections); } } } @@ -131,8 +163,12 @@ async fn process_connection(stream: TcpStream, vault: Arc, action_pool: A let mut instance = ConnectionInstance::from(stream); // Read action name and action arguments - let Ok(msg) = instance.read_msgpack::().await else { - return; + let msg = match instance.read_msgpack::().await { + Ok(msg) => msg, + Err(e) => { + error!("Failed to read action message: {}", e); + return; + } }; // Build context @@ -141,11 +177,21 @@ async fn process_connection(stream: TcpStream, vault: Arc, action_pool: A // Insert vault into context let ctx = ctx.insert_arc(vault); + info!( + "Process action `{}` with argument `{}`", + msg.action_name, msg.action_args_json + ); + // Process action - let Ok(_result_json) = action_pool + let result = action_pool .process_json(&msg.action_name, ctx, msg.action_args_json) - .await - else { - return; + .await; + + match result { + Ok(_result_json) => {} + Err(e) => { + warn!("Failed to process action `{}`: {}", msg.action_name, e); + return; + } }; } -- cgit From 3d638844da6b540b1e70e25e6f7c49307b240078 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:15:30 +0800 Subject: feat: Add Server Lock --- crates/vcs_data/src/data/vault/service.rs | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 crates/vcs_data/src/data/vault/service.rs (limited to 'crates') diff --git a/crates/vcs_data/src/data/vault/service.rs b/crates/vcs_data/src/data/vault/service.rs new file mode 100644 index 0000000..9fdce85 --- /dev/null +++ b/crates/vcs_data/src/data/vault/service.rs @@ -0,0 +1,43 @@ +use std::path::PathBuf; + +use crate::{constants::SERVER_FILE_LOCKFILE, data::vault::Vault}; + +impl Vault { + /// Get the path of the lock file for the current Vault + pub fn lock_file_path(&self) -> PathBuf { + self.vault_path().join(SERVER_FILE_LOCKFILE) + } + + /// Check if the current Vault is locked + pub fn is_locked(&self) -> bool { + self.lock_file_path().exists() + } + + /// Lock the current Vault + pub fn lock(&self) -> Result<(), std::io::Error> { + if self.is_locked() { + return Err(std::io::Error::new( + std::io::ErrorKind::AlreadyExists, + format!( + "Vault is already locked at {}. \ + To unlock, please stop any running services. \ + If you are certain no services are running, \ + please delete this file", + self.lock_file_path().display() + ), + )); + } + std::fs::File::create(self.lock_file_path())?; + Ok(()) + } + + /// Unlock the current Vault + pub fn unlock(&self) -> Result<(), std::io::Error> { + if let Err(e) = std::fs::remove_file(self.lock_file_path()) { + if e.kind() != std::io::ErrorKind::NotFound { + return Err(e); + } + } + Ok(()) + } +} -- cgit From 45cee7d8def7738d3347b201d3c54c0055817a4c Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:20:01 +0800 Subject: fix: Make the ActionContext passed to on_proc_begin mutable --- crates/system_action/action_macros/src/lib.rs | 2 +- crates/system_action/src/action_pool.rs | 12 ++++++------ crates/vcs_actions/src/registry/client_registry.rs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'crates') diff --git a/crates/system_action/action_macros/src/lib.rs b/crates/system_action/action_macros/src/lib.rs index ce50073..7362cdf 100644 --- a/crates/system_action/action_macros/src/lib.rs +++ b/crates/system_action/action_macros/src/lib.rs @@ -64,7 +64,7 @@ fn generate_action_struct(input_fn: ItemFn, _is_local: bool) -> proc_macro2::Tok #fn_vis async fn #proc_this_action( pool: &action_system::action_pool::ActionPool, - ctx: action_system::action::ActionContext, + mut ctx: action_system::action::ActionContext, #arg_param_name: #arg_type ) -> Result<#return_type, tcp_connection::error::TcpTargetError> { let args_json = serde_json::to_string(&#arg_param_name) diff --git a/crates/system_action/src/action_pool.rs b/crates/system_action/src/action_pool.rs index c28de1e..c3ad4a1 100644 --- a/crates/system_action/src/action_pool.rs +++ b/crates/system_action/src/action_pool.rs @@ -7,7 +7,7 @@ use tcp_connection::error::TcpTargetError; use crate::action::{Action, ActionContext}; type ProcBeginCallback = for<'a> fn( - &'a ActionContext, + &'a mut ActionContext, args: &'a (dyn std::any::Any + Send + Sync), ) -> ProcBeginFuture<'a>; type ProcEndCallback = fn() -> ProcEndFuture; @@ -94,9 +94,9 @@ impl ActionPool { if let Some(action) = self.actions.get(action_name) { // Set action name and args in context for callbacks let context = context.set_action_name(action_name.to_string()); - let context = context.set_action_args(args_json.clone()); + let mut context = context.set_action_args(args_json.clone()); - self.exec_on_proc_begin(&context, &args_json).await?; + self.exec_on_proc_begin(&mut context, &args_json).await?; let result = action.process_json_erased(context, args_json).await?; self.exec_on_proc_end().await?; Ok(result) @@ -114,7 +114,7 @@ impl ActionPool { pub async fn process<'a, Args, Return>( &'a self, action_name: &'a str, - context: ActionContext, + mut context: ActionContext, args: Args, ) -> Result where @@ -122,7 +122,7 @@ impl ActionPool { Return: serde::Serialize + Send + 'static, { if let Some(action) = self.actions.get(action_name) { - self.exec_on_proc_begin(&context, &args).await?; + self.exec_on_proc_begin(&mut context, &args).await?; let result = action.process_erased(context, Box::new(args)).await?; let result = *result .downcast::() @@ -137,7 +137,7 @@ impl ActionPool { /// Executes the process begin callback if set async fn exec_on_proc_begin( &self, - context: &ActionContext, + context: &mut ActionContext, args: &(dyn std::any::Any + Send + Sync), ) -> Result<(), TcpTargetError> { if let Some(callback) = &self.on_proc_begin { diff --git a/crates/vcs_actions/src/registry/client_registry.rs b/crates/vcs_actions/src/registry/client_registry.rs index 484c4f4..a108910 100644 --- a/crates/vcs_actions/src/registry/client_registry.rs +++ b/crates/vcs_actions/src/registry/client_registry.rs @@ -26,7 +26,7 @@ pub fn client_action_pool() -> ActionPool { } async fn on_proc_begin( - ctx: &ActionContext, + ctx: &mut ActionContext, _args: &(dyn std::any::Any + Send + Sync), ) -> Result<(), TcpTargetError> { // Is ctx remote -- cgit From 9766cdc3f0a741a7548c413297425efd298af8f2 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:20:31 +0800 Subject: "fix: Fix indentation issues --- crates/system_action/action_macros/src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/system_action/action_macros/src/lib.rs b/crates/system_action/action_macros/src/lib.rs index 7362cdf..f65d424 100644 --- a/crates/system_action/action_macros/src/lib.rs +++ b/crates/system_action/action_macros/src/lib.rs @@ -121,11 +121,12 @@ fn validate_function_signature(fn_sig: &syn::Signature) { if let syn::Type::Path(type_path) = return_type.as_ref() { if let Some(segment) = type_path.path.segments.last() - && segment.ident != "Result" { - panic!( - "Expected Action function to return Result, but found different return type" - ); - } + && segment.ident != "Result" + { + panic!( + "Expected Action function to return Result, but found different return type" + ); + } } else { panic!( "Expected Action function to return Result, but found no return type" -- cgit From 2954fc5ce35126e4cf9ebfc64043c0e52a990e01 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:38:28 +0800 Subject: update: ActionContext 1. Rename `local` to `proc_on_local` 2. Add `is_remote_action` --- crates/system_action/src/action.rs | 27 ++++++++++++++++++------- crates/vcs_actions/src/actions/local_actions.rs | 8 ++++---- 2 files changed, 24 insertions(+), 11 deletions(-) (limited to 'crates') diff --git a/crates/system_action/src/action.rs b/crates/system_action/src/action.rs index 8a6180a..9eef1db 100644 --- a/crates/system_action/src/action.rs +++ b/crates/system_action/src/action.rs @@ -23,7 +23,10 @@ where #[derive(Default)] pub struct ActionContext { /// Whether the action is executed locally or remotely - local: bool, + proc_on_local: bool, + + /// Whether the action being executed in the current context is a remote action + is_remote_action: bool, /// The name of the action being executed action_name: String, @@ -42,7 +45,7 @@ impl ActionContext { /// Generate local context pub fn local() -> Self { ActionContext { - local: true, + proc_on_local: true, ..Default::default() } } @@ -50,7 +53,7 @@ impl ActionContext { /// Generate remote context pub fn remote() -> Self { ActionContext { - local: false, + proc_on_local: false, ..Default::default() } } @@ -75,13 +78,23 @@ impl ActionContext { impl ActionContext { /// Whether the action is executed locally - pub fn is_local(&self) -> bool { - self.local + pub fn is_proc_on_local(&self) -> bool { + self.proc_on_local } /// Whether the action is executed remotely - pub fn is_remote(&self) -> bool { - !self.local + pub fn is_proc_on_remote(&self) -> bool { + !self.proc_on_local + } + + /// Whether the action being executed in the current context is a remote action + pub fn is_remote_action(&self) -> bool { + self.is_remote_action + } + + /// Set whether the action being executed in the current context is a remote action + pub fn set_is_remote_action(&mut self, is_remote_action: bool) { + self.is_remote_action = is_remote_action; } /// Get the connection instance in the current context diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs index c2d9f4f..e2788ff 100644 --- a/crates/vcs_actions/src/actions/local_actions.rs +++ b/crates/vcs_actions/src/actions/local_actions.rs @@ -13,10 +13,10 @@ pub async fn hello_world_action(ctx: ActionContext, _n: ()) -> Result<(), TcpTar )); }; - if ctx.is_local() { + if ctx.is_proc_on_local() { // Local execution - communication is handled by on_proc_begin info!("Hello World action executed locally"); - } else if ctx.is_remote() { + } else if ctx.is_proc_on_remote() { // Remote execution - read the message from the client let read = instance.lock().await.read_text().await?; info!("{}", read) @@ -37,11 +37,11 @@ pub async fn set_upstream_vault_action( )); }; - if ctx.is_local() { + if ctx.is_proc_on_local() { // Invoke on local // Send the message to the server let _ = instance.lock().await.write_text("Hello World!").await; - } else if ctx.is_remote() { + } else if ctx.is_proc_on_remote() { // Remote execution - read the message from the client let read = instance.lock().await.read_text().await?; info!("Received: {}", read) -- cgit From 3aafc7f2769284c3afab4157863e93e44c571040 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:45:01 +0800 Subject: fixed: Incorrect condition setting for determining whether to send parameters during `on_proc_begin` --- crates/system_action/action_macros/src/lib.rs | 1 + crates/vcs_actions/src/registry/client_registry.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/system_action/action_macros/src/lib.rs b/crates/system_action/action_macros/src/lib.rs index f65d424..4c03b63 100644 --- a/crates/system_action/action_macros/src/lib.rs +++ b/crates/system_action/action_macros/src/lib.rs @@ -67,6 +67,7 @@ fn generate_action_struct(input_fn: ItemFn, _is_local: bool) -> proc_macro2::Tok mut ctx: action_system::action::ActionContext, #arg_param_name: #arg_type ) -> Result<#return_type, tcp_connection::error::TcpTargetError> { + ctx.set_is_remote_action(!#_is_local); let args_json = serde_json::to_string(&#arg_param_name) .map_err(|e| { tcp_connection::error::TcpTargetError::Serialization(e.to_string()) diff --git a/crates/vcs_actions/src/registry/client_registry.rs b/crates/vcs_actions/src/registry/client_registry.rs index a108910..9769750 100644 --- a/crates/vcs_actions/src/registry/client_registry.rs +++ b/crates/vcs_actions/src/registry/client_registry.rs @@ -30,7 +30,7 @@ async fn on_proc_begin( _args: &(dyn std::any::Any + Send + Sync), ) -> Result<(), TcpTargetError> { // Is ctx remote - let is_remote = ctx.is_remote(); + let is_remote = ctx.is_remote_action(); // Action name and arguments let action_name = ctx.action_name().to_string(); -- cgit From cab9c998bcb2a6ea4ee51ff39d708ac6755dcb75 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:47:42 +0800 Subject: update: Add error type - Locked --- crates/utils/tcp_connection/src/error.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'crates') diff --git a/crates/utils/tcp_connection/src/error.rs b/crates/utils/tcp_connection/src/error.rs index 28e33d3..cfea060 100644 --- a/crates/utils/tcp_connection/src/error.rs +++ b/crates/utils/tcp_connection/src/error.rs @@ -44,6 +44,9 @@ pub enum TcpTargetError { #[error("Not found: {0}")] NotFound(String), + + #[error("Locked: {0}")] + Locked(String), } impl From for TcpTargetError { -- cgit From 5212da62bb6d7b3e0eb8d9b2801cc8d1d7ef4ece Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:50:05 +0800 Subject: update: Remove `hello_world_action` --- crates/vcs_actions/src/actions/local_actions.rs | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'crates') diff --git a/crates/vcs_actions/src/actions/local_actions.rs b/crates/vcs_actions/src/actions/local_actions.rs index e2788ff..f705692 100644 --- a/crates/vcs_actions/src/actions/local_actions.rs +++ b/crates/vcs_actions/src/actions/local_actions.rs @@ -4,27 +4,6 @@ use action_system::{action::ActionContext, macros::action_gen}; use log::info; use tcp_connection::error::TcpTargetError; -#[action_gen] -pub async fn hello_world_action(ctx: ActionContext, _n: ()) -> Result<(), TcpTargetError> { - // Ensure the instance is available - let Some(instance) = ctx.instance() else { - return Err(TcpTargetError::NotFound( - "Connection Instance Lost.".to_string(), - )); - }; - - if ctx.is_proc_on_local() { - // Local execution - communication is handled by on_proc_begin - info!("Hello World action executed locally"); - } else if ctx.is_proc_on_remote() { - // Remote execution - read the message from the client - let read = instance.lock().await.read_text().await?; - info!("{}", read) - } - - Ok(()) -} - #[action_gen] pub async fn set_upstream_vault_action( ctx: ActionContext, -- cgit From 60219b20754dda7f560deb5e9e442d46e4636507 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:50:35 +0800 Subject: update: Add server lock behavior to vault lifecycle Lock the vault before starting the server and unlock it during shutdown. --- crates/vcs_actions/src/connection/action_service.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'crates') diff --git a/crates/vcs_actions/src/connection/action_service.rs b/crates/vcs_actions/src/connection/action_service.rs index f76921e..a657408 100644 --- a/crates/vcs_actions/src/connection/action_service.rs +++ b/crates/vcs_actions/src/connection/action_service.rs @@ -31,6 +31,12 @@ pub async fn server_entry(vault_path: impl Into) -> Result<(), TcpTarge // Initialize the vault let vault: Arc = init_vault(vault_cfg, vault_path.into()).await?; + // Lock the vault + vault.lock().map_err(|e| { + error!("{}", e); + TcpTargetError::Locked(e.to_string()) + })?; + // Create ActionPool let action_pool: Arc = Arc::new(server_action_pool()); @@ -38,6 +44,9 @@ pub async fn server_entry(vault_path: impl Into) -> Result<(), TcpTarge let (_shutdown_rx, future) = build_server_future(vault.clone(), action_pool.clone(), listener); future.await?; // Start and block until shutdown + // Unlock the vault + vault.unlock()?; + Ok(()) } -- cgit From b772e12c22b87e1473d1002ef9b82d954d2239a7 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:51:07 +0800 Subject: update: Add connection logs to show active count Include current connection count in connection open/close log messages for better monitoring of server load --- crates/vcs_actions/src/connection/action_service.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/vcs_actions/src/connection/action_service.rs b/crates/vcs_actions/src/connection/action_service.rs index a657408..f787cae 100644 --- a/crates/vcs_actions/src/connection/action_service.rs +++ b/crates/vcs_actions/src/connection/action_service.rs @@ -118,7 +118,7 @@ fn build_server_future( accept_result = listener.accept(), if !shutdown_requested => { match accept_result { Ok((stream, _addr)) => { - info!("New connection accepted."); + info!("New connection. (now {})", active_connections); let _ = tx.send(1).await; let vault_clone = vault.clone(); @@ -127,7 +127,7 @@ fn build_server_future( spawn(async move { process_connection(stream, vault_clone, action_pool_clone).await; - info!("A connection closed."); + info!("A connection closed. (now {})", active_connections); let _ = tx_clone.send(-1).await; }); } -- cgit From e1fbe3648b07dfd31afabfdbb762d45eaaeb8c19 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:51:38 +0800 Subject: update: Remove unused inline comments from constants --- crates/vcs_data/src/constants.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/vcs_data/src/constants.rs b/crates/vcs_data/src/constants.rs index 5e147c4..89bc732 100644 --- a/crates/vcs_data/src/constants.rs +++ b/crates/vcs_data/src/constants.rs @@ -12,7 +12,7 @@ pub const VAULT_HOST_NAME: &str = "host"; // Server // Server - Vault (Main) -pub const SERVER_FILE_VAULT: &str = "./vault.toml"; // crates::env::vault::vault_config +pub const SERVER_FILE_VAULT: &str = "./vault.toml"; // Server - Sheets pub const REF_SHEET_NAME: &str = "ref"; @@ -22,8 +22,8 @@ pub const SERVER_FILE_SHEET: &str = "./sheets/{sheet-name}.yaml"; // Server - Members pub const SERVER_PATH_MEMBERS: &str = "./members/"; pub const SERVER_PATH_MEMBER_PUB: &str = "./key/"; -pub const SERVER_FILE_MEMBER_INFO: &str = "./members/{member_id}.toml"; // crates::env::member::manager -pub const SERVER_FILE_MEMBER_PUB: &str = "./key/{member_id}.pem"; // crates::utils::tcp_connection::instance +pub const SERVER_FILE_MEMBER_INFO: &str = "./members/{member_id}.toml"; +pub const SERVER_FILE_MEMBER_PUB: &str = "./key/{member_id}.pem"; // Server - Virtual File Storage pub const SERVER_PATH_VF_TEMP: &str = "./.temp/{temp_name}"; @@ -40,10 +40,10 @@ pub const SERVER_FILE_README: &str = "./README.md"; pub const CLIENT_PATH_WORKSPACE_ROOT: &str = "./.jv/"; // Client - Workspace (Main) -pub const CLIENT_FILE_WORKSPACE: &str = "./.jv/workspace.toml"; // crates::env::local::local_config +pub const CLIENT_FILE_WORKSPACE: &str = "./.jv/workspace.toml"; // Client - Other -pub const CLIENT_FILE_IGNOREFILES: &str = ".jgnore .gitignore"; // Support gitignore file. +pub const CLIENT_FILE_IGNOREFILES: &str = "IGNORE_RULES.toml"; pub const CLIENT_FILE_README: &str = "./README.md"; // ------------------------------------------------------------------------------------- -- cgit From 4beaa221cefb8a273453a1abf4fc98649d509b23 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:52:14 +0800 Subject: Add lockfile constant for server service --- crates/vcs_data/src/constants.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'crates') diff --git a/crates/vcs_data/src/constants.rs b/crates/vcs_data/src/constants.rs index 89bc732..7514fe2 100644 --- a/crates/vcs_data/src/constants.rs +++ b/crates/vcs_data/src/constants.rs @@ -32,6 +32,9 @@ pub const SERVER_PATH_VF_STORAGE: &str = "./storage/{vf_index}/{vf_id}/"; pub const SERVER_FILE_VF_VERSION_INSTANCE: &str = "./storage/{vf_index}/{vf_id}/{vf_version}.rf"; pub const SERVER_FILE_VF_META: &str = "./storage/{vf_index}/{vf_id}/meta.yaml"; +// Server - Service +pub const SERVER_FILE_LOCKFILE: &str = "./.lock"; + pub const SERVER_FILE_README: &str = "./README.md"; // ------------------------------------------------------------------------------------- -- cgit From 368687c943a13427b5338a30fb7b55558420f4de Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 27 Oct 2025 17:52:35 +0800 Subject: Add service module to vault --- crates/vcs_data/src/data/vault.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates') diff --git a/crates/vcs_data/src/data/vault.rs b/crates/vcs_data/src/data/vault.rs index 5d17a81..80ebe1d 100644 --- a/crates/vcs_data/src/data/vault.rs +++ b/crates/vcs_data/src/data/vault.rs @@ -17,6 +17,7 @@ use crate::{ pub mod config; pub mod member; +pub mod service; pub mod sheets; pub mod virtual_file; -- cgit