Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create TaskStatusEvent trait instead of piggybacking on Error #4919

Merged
merged 5 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions common/bandwidth-controller/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ thiserror = { workspace = true }
url = { workspace = true }
zeroize = { workspace = true }

nym-ecash-time = { path = "../ecash-time" }
nym-credential-storage = { path = "../credential-storage" }
nym-credentials = { path = "../credentials" }
nym-credentials-interface = { path = "../credentials-interface" }
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "stream_cipher", "aes", "hashing"] }
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }
nym-ecash-time = { path = "../ecash-time" }
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }

[target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client]
path = "../client-libs/validator-client"
Expand Down
24 changes: 18 additions & 6 deletions common/bandwidth-controller/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
// Copyright 2024 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

// See other comments for other TaskStatus message enumds about abusing the Error trait when we
// should have a new trait for TaskStatus messages
#[derive(Debug, thiserror::Error)]
#[derive(Debug)]
pub enum BandwidthStatusMessage {
#[error("remaining bandwidth: {0}")]
RemainingBandwidth(i64),

#[error("no bandwidth left")]
NoBandwidth,
}

impl std::fmt::Display for BandwidthStatusMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BandwidthStatusMessage::RemainingBandwidth(b) => {
write!(f, "remaining bandwidth: {}", b)
}
BandwidthStatusMessage::NoBandwidth => write!(f, "no bandwidth left"),
}
}
}

impl nym_task::TaskStatusEvent for BandwidthStatusMessage {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
27 changes: 22 additions & 5 deletions common/client-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,29 @@ pub enum ClientCoreError {
}

/// Set of messages that the client can send to listeners via the task manager
#[derive(thiserror::Error, Debug)]
#[derive(Debug)]
pub enum ClientCoreStatusMessage {
// NOTE: The nym-connect frontend listens for these strings, so don't change them until we have a more robust mechanism in place
#[error("The connected gateway is slow, or the connection to it is slow")]
GatewayIsSlow,
// NOTE: The nym-connect frontend listens for these strings, so don't change them until we have a more robust mechanism in place
#[error("The connected gateway is very slow, or the connection to it is very slow")]
GatewayIsVerySlow,
}

impl std::fmt::Display for ClientCoreStatusMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ClientCoreStatusMessage::GatewayIsSlow => write!(
f,
"The connected gateway is slow, or the connection to it is slow"
),
ClientCoreStatusMessage::GatewayIsVerySlow => write!(
f,
"The connected gateway is very slow, or the connection to it is very slow"
),
}
}
}

impl nym_task::TaskStatusEvent for ClientCoreStatusMessage {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
6 changes: 6 additions & 0 deletions common/socks5-client-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ impl From<ConnectionError> for Socks5ClientCoreError {
}
}
}

impl nym_task::TaskStatusEvent for Socks5ClientCoreError {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
3 changes: 1 addition & 2 deletions common/socks5-client-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ use nym_client_core::init::types::GatewaySetup;
use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::params::PacketType;
use nym_task::manager::TaskStatus;
use nym_task::{TaskClient, TaskHandle};
use nym_task::{TaskClient, TaskHandle, TaskStatus};

use anyhow::anyhow;
use nym_validator_client::UserAgent;
Expand Down
35 changes: 35 additions & 0 deletions common/task/src/event.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use std::{any::Any, fmt};

pub type SentStatus = Box<dyn TaskStatusEvent>;
pub type StatusSender = futures::channel::mpsc::Sender<SentStatus>;
pub type StatusReceiver = futures::channel::mpsc::Receiver<SentStatus>;

pub trait TaskStatusEvent: Send + Sync + Any + fmt::Display {
fn as_any(&self) -> &dyn Any;
}

#[derive(Debug, PartialEq, Eq)]
pub enum TaskStatus {
Ready,
ReadyWithGateway(String),
}

impl fmt::Display for TaskStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TaskStatus::Ready => write!(f, "Ready"),
TaskStatus::ReadyWithGateway(gateway) => {
write!(f, "Ready and connected to gateway: {gateway}")
}
}
}
}

impl TaskStatusEvent for TaskStatus {
fn as_any(&self) -> &dyn Any {
self
}
}
4 changes: 3 additions & 1 deletion common/task/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
// SPDX-License-Identifier: Apache-2.0

pub mod connections;
pub mod event;
pub mod manager;
#[cfg(not(target_arch = "wasm32"))]
pub mod signal;
pub mod spawn;

pub use manager::{StatusReceiver, StatusSender, TaskClient, TaskHandle, TaskManager};
pub use event::{StatusReceiver, StatusSender, TaskStatus, TaskStatusEvent};
pub use manager::{TaskClient, TaskHandle, TaskManager};
#[cfg(not(target_arch = "wasm32"))]
pub use signal::wait_for_signal_and_error;

Expand Down
23 changes: 8 additions & 15 deletions common/task/src/manager.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
// Copyright 2022 - Nym Technologies SA <[email protected]>
// SPDX-License-Identifier: Apache-2.0

use std::{
error::Error,
sync::atomic::{AtomicBool, Ordering},
time::Duration,
};

use futures::{future::pending, FutureExt, SinkExt, StreamExt};
use log::{log, Level};
use std::sync::atomic::{AtomicBool, Ordering};
use std::{error::Error, time::Duration};
use tokio::sync::{
mpsc,
watch::{self, error::SendError},
};

use crate::event::{SentStatus, StatusReceiver, StatusSender, TaskStatus};

#[cfg(not(target_arch = "wasm32"))]
use tokio::time::{sleep, timeout};

Expand All @@ -22,10 +28,6 @@ pub(crate) type SentError = Box<dyn Error + Send + Sync>;
type ErrorSender = mpsc::UnboundedSender<SentError>;
type ErrorReceiver = mpsc::UnboundedReceiver<SentError>;

pub type SentStatus = Box<dyn Error + Send + Sync>;
pub type StatusSender = futures::channel::mpsc::Sender<SentStatus>;
pub type StatusReceiver = futures::channel::mpsc::Receiver<SentStatus>;

fn try_recover_name(name: &Option<String>) -> String {
if let Some(name) = name {
name.clone()
Expand All @@ -40,15 +42,6 @@ enum TaskError {
UnexpectedHalt { shutdown_name: Option<String> },
}

// TODO: possibly we should create a `Status` trait instead of reusing `Error`
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
pub enum TaskStatus {
#[error("Ready")]
Ready,
#[error("Ready and connected to gateway: {0}")]
ReadyWithGateway(String),
}

/// Listens to status and error messages from tasks, as well as notifying them to gracefully
/// shutdown. Keeps track of if task stop unexpectedly, such as in a panic.
#[derive(Debug)]
Expand Down
4 changes: 2 additions & 2 deletions sdk/rust/nym-sdk/src/mixnet/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ use nym_client_core::init::setup_gateway;
use nym_client_core::init::types::{GatewaySelectionSpecification, GatewaySetup};
use nym_credentials_interface::TicketType;
use nym_socks5_client_core::config::Socks5;
use nym_task::manager::TaskStatus;
use nym_task::{TaskClient, TaskHandle};
use nym_task::{TaskClient, TaskHandle, TaskStatus};
use nym_topology::provider_trait::TopologyProvider;
use nym_validator_client::{nyxd, QueryHttpRpcNyxdClient, UserAgent};
use rand::rngs::OsRng;
Expand Down Expand Up @@ -655,6 +654,7 @@ where
.next()
.await
.ok_or(Error::Socks5NotStarted)?
.as_any()
.downcast_ref::<TaskStatus>()
.ok_or(Error::Socks5NotStarted)?
{
Expand Down
Loading