Skip to content

Commit

Permalink
(#85) VSCode extension - Many improvement with backend synch
Browse files Browse the repository at this point in the history
  • Loading branch information
mario4tier committed Jun 19, 2024
1 parent 342da13 commit 9fc71c6
Show file tree
Hide file tree
Showing 33 changed files with 2,055 additions and 1,243 deletions.
12 changes: 6 additions & 6 deletions rust/demo-app/move/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ dependencies = [
]

[move.toolchain-version]
compiler-version = "1.26.1"
compiler-version = "1.27.0"
edition = "2024.beta"
flavor = "sui"

Expand All @@ -42,13 +42,13 @@ flavor = "sui"
test = 12

[env.localnet_proxy]
chain-id = "8b58d781"
original-published-id = "0xa2baf7d76bd05998cae8ee4935fcea70339980a2e23c42c575c3f467de02b788"
latest-published-id = "0xa2baf7d76bd05998cae8ee4935fcea70339980a2e23c42c575c3f467de02b788"
chain-id = "40324676"
original-published-id = "0x5c9c7994b79cdfd79bad2998ec38e53291696aa774094ee67e559be7d68a347d"
latest-published-id = "0x5c9c7994b79cdfd79bad2998ec38e53291696aa774094ee67e559be7d68a347d"
published-version = "1"

[env.testnet_proxy]
chain-id = "4c78adac"
original-published-id = "0xf74d92fa3f9836bb4294155ccd209a44117dd324ffcc8bddced7f40ca758d60e"
latest-published-id = "0xf74d92fa3f9836bb4294155ccd209a44117dd324ffcc8bddced7f40ca758d60e"
original-published-id = "0x3630f0970843e9808fec206b5f2bdd9f8ab49f4972dee0fdf0a93e46aa14517c"
latest-published-id = "0x3630f0970843e9808fec206b5f2bdd9f8ab49f4972dee0fdf0a93e46aa14517c"
published-version = "1"
24 changes: 20 additions & 4 deletions rust/suibase/crates/DESIGN-README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
**Layers**

Dependencies (top to bottom)

entry point main.rs
periodic event generator: clock_trigger
orchestrator task: admin_controller
high level tasks: network_monitor, proxy_server, cli_poller...
low level tasks: workers::log_worker, workers::websocket_worker...
data structures: shared_types

common::workers
common::utils
common::shared_types
common::basic_types

**Crates**
common
======
Expand Down Expand Up @@ -27,9 +43,9 @@ All daemon uses:
- Tokio thread and async Mutex/RwLock.
- Generic error handling with 'anyhow'.
- Mostly Arc<RwLock> globals for multi-threading safe data sharing.
- Most threads supports auto-restart on panic. This is implemented with
- Most threads supports auto-restart on panic. This is implemented with
https://docs.rs/tokio-graceful-shutdown/latest/tokio_graceful_shutdown/

**State Coordination**
Because thread can be restarted at any time, we need to be careful about state coordination.

Expand All @@ -38,8 +54,8 @@ State change are mostly reactive (inform all consumer of the change with message
All threads are design to handle 3 type of messages:

- EVENT_AUDIT: A fast consistency check. Read-only access to shared variables for performance reason. Should emit an EVENT_UPDATE to self when detecting the need to mutate a shared variable (e.g. globals).

- EVENT_UPDATE: Similar to audit, but allowed to apply shared variables state changes.

- EVENT_EXEC: This is the reactive mechanism to execute what is specified by the params (command, data_string...). Shared variables (e.g. globals) write access allowed.

2 changes: 1 addition & 1 deletion rust/suibase/crates/common/src/basic_types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This is a submodule specific to suibase-daemon.
//
// flatten everything under "api" module.
// flatten everything under "common::basic_types" module.
pub use self::auto_thread::*;
pub use self::autosize_vec::*;
pub use self::autosize_vec_map_vec::*;
Expand Down
13 changes: 13 additions & 0 deletions rust/suibase/crates/common/src/basic_types/suibase_basic_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,19 @@ pub struct GenericChannelMsg {
pub resp_channel: Option<tokio::sync::oneshot::Sender<String>>,
}

impl Clone for GenericChannelMsg {
fn clone(&self) -> Self {
Self {
event_id: self.event_id,
command: self.command.clone(),
params: self.params.clone(),
data_json: self.data_json.clone(),
workdir_idx: self.workdir_idx,
resp_channel: None, // Watch-out... resp_channel is not cloneable!
}
}
}

impl GenericChannelMsg {
pub fn new() -> Self {
Self::default()
Expand Down
1 change: 1 addition & 0 deletions rust/suibase/crates/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[allow(dead_code)]
pub mod basic_types;
pub mod shared_types;
pub mod utils;
pub mod workers;
2 changes: 1 addition & 1 deletion rust/suibase/crates/common/src/shared_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// This is a submodule specific to suibase-daemon.
//
// flatten everything under "shared_type" module.
// flatten everything under "common::shared_type" module.
pub use self::workdirs::*;

mod workdirs;
4 changes: 4 additions & 0 deletions rust/suibase/crates/common/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// flatten everything under "common::utils" module.
pub use self::strings::*;

mod strings;
17 changes: 17 additions & 0 deletions rust/suibase/crates/common/src/utils/strings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Standalone functions to manipulate strings
pub fn remove_ascii_color_code(s: &str) -> String {
let mut result = String::new();
let mut is_color_code = false;
for c in s.chars() {
if is_color_code {
if c == 'm' {
is_color_code = false;
}
} else if c == '\x1b' {
is_color_code = true;
} else {
result.push(c);
}
}
result
}
2 changes: 1 addition & 1 deletion rust/suibase/crates/common/src/workers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This is a submodule specific to suibase-daemon.
//
// flatten everything under "api" module.
// flatten everything under "common::workders" module.
pub use self::shell_worker::*;
pub use self::subscription_tracking::*;

Expand Down
66 changes: 54 additions & 12 deletions rust/suibase/crates/dtp-daemon/src/admin_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ pub type AdminControllerRx = tokio::sync::mpsc::Receiver<AdminControllerMsg>;
struct WorkdirTracking {
last_read_config: Option<WorkdirUserConfig>,

shell_worker_tx: Option<GenericTx>,
shell_worker_handle: Option<NestedSubsystem<Box<dyn Error + Send + Sync>>>, // Set when the shell_worker is started.
// Two shell workers.
// First is for any "mutating and long running" commands (e.g. stop,start,regen...)
// Second is for fast status and set-active commands.
shell_slow_worker_tx: Option<GenericTx>,
shell_slow_worker_handle: Option<NestedSubsystem<Box<dyn Error + Send + Sync>>>, // Set when the shell_worker is started.

shell_fast_worker_tx: Option<GenericTx>,
shell_fast_worker_handle: Option<NestedSubsystem<Box<dyn Error + Send + Sync>>>, // Set when the shell_worker is started.

events_worker_tx: Option<WebSocketWorkerTx>,
events_worker_handle: Option<NestedSubsystem<Box<dyn Error + Send + Sync>>>, // Set when the events_writer_worker is started.
Expand Down Expand Up @@ -231,30 +237,66 @@ impl AdminController {
// Find the corresponding ShellWorker in wd_tracking using the workdir_idx.
let wd_tracking = self.wd_tracking.get_mut(workdir_idx);

// Instantiate and start the ShellWorker if not already done.
if wd_tracking.shell_worker_handle.is_none() {
// Instantiate and start the ShellWorkers when not already done.
if wd_tracking.shell_slow_worker_handle.is_none() {
let (shell_worker_tx, shell_worker_rx) = tokio::sync::mpsc::channel(MPSC_Q_SIZE);
wd_tracking.shell_worker_tx = Some(shell_worker_tx);
wd_tracking.shell_slow_worker_tx = Some(shell_worker_tx);
let shell_worker =
ShellWorker::new(self.globals.clone(), shell_worker_rx, Some(workdir_idx));
let nested = subsys.start(SubsystemBuilder::new("shell-worker", |a| {
shell_worker.run(a)
}));
wd_tracking.shell_worker_handle = Some(nested);

let nested = subsys.start(SubsystemBuilder::new(
format!("shell-slow-worker-{}", workdir_idx),
|a| shell_worker.run(a),
));
wd_tracking.shell_slow_worker_handle = Some(nested);
}

if wd_tracking.shell_worker_tx.is_none() {
log::error!("EVENT_SHELL_EXEC missing shell_worker_tx");
if wd_tracking.shell_slow_worker_tx.is_none() {
log::error!("EVENT_SHELL_EXEC missing shell_slow_worker_tx");
return;
}
let shell_worker_tx = wd_tracking.shell_worker_tx.as_ref().unwrap();

if wd_tracking.shell_fast_worker_handle.is_none() {
let (shell_worker_tx, shell_worker_rx) = tokio::sync::mpsc::channel(MPSC_Q_SIZE);
wd_tracking.shell_fast_worker_tx = Some(shell_worker_tx);
let shell_worker =
ShellWorker::new(self.globals.clone(), shell_worker_rx, Some(workdir_idx));
let nested = subsys.start(SubsystemBuilder::new(
format!("shell-fast-worker-{}", workdir_idx),
|a| shell_worker.run(a),
));
wd_tracking.shell_fast_worker_handle = Some(nested);
}

if wd_tracking.shell_fast_worker_tx.is_none() {
log::error!("EVENT_SHELL_EXEC missing shell_fast_worker_tx");
return;
}

// Identify if the second word of the command is either "status" or "set-active".
let mut is_fast_command = false;
if let Some(command) = msg.data_string.as_ref() {
let mut words = command.split_whitespace();
if let Some(second_word) = words.nth(1) {
if second_word == "status" || second_word == "set-active" {
is_fast_command = true;
}
}
};

// Forward the message to the ShellWorker.
let mut worker_msg = GenericChannelMsg::new();
worker_msg.event_id = EVENT_EXEC;
worker_msg.command = msg.data_string;
worker_msg.workdir_idx = msg.workdir_idx;
worker_msg.resp_channel = msg.resp_channel;

let shell_worker_tx = if is_fast_command {
wd_tracking.shell_fast_worker_tx.as_ref().unwrap()
} else {
wd_tracking.shell_slow_worker_tx.as_ref().unwrap()
};

if let Err(e) = shell_worker_tx.try_send(worker_msg) {
let err_msg = format!("try_send EVENT_SHELL_EXEC to worker failed: {}", e);
log_safe!(err_msg);
Expand Down
5 changes: 0 additions & 5 deletions rust/suibase/crates/dtp-daemon/src/api/def_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,6 @@ pub struct WorkdirStatusResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub network_version: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub asui_selection: Option<String>,

// Finer grain status for each process/feature/service.
#[serde(skip_serializing_if = "Option::is_none")]
pub services: Option<Vec<StatusService>>,
Expand All @@ -267,7 +264,6 @@ impl WorkdirStatusResponse {
status_info: None,
client_version: None,
network_version: None,
asui_selection: None,
services: None,
display: None,
debug: None,
Expand All @@ -288,7 +284,6 @@ impl VersionedEq for WorkdirStatusResponse {
&& self.status_info == other.status_info
&& self.client_version == other.client_version
&& self.network_version == other.network_version
&& self.asui_selection == other.asui_selection
&& self.services == other.services
}
}
Expand Down
4 changes: 2 additions & 2 deletions rust/suibase/crates/dtp-daemon/src/api/impl_general_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,10 @@ impl GeneralApiImpl {
resp.header.method = "getWorkdirStatus".to_string();
resp.header.key = Some(workdir.clone());

// Get an update with a "<workdir> status --json" shell call.
// TODO Get an update with a "<workdir> status --json" shell call.
// Map it into the resp.
let cmd_resp = match self
.shell_exec(workdir_idx, format!("{} status", workdir))
.shell_exec(workdir_idx, format!("{} status --daemoncall", workdir))
.await
{
Ok(cmd_resp) => cmd_resp,
Expand Down
Loading

0 comments on commit 9fc71c6

Please sign in to comment.