From 3363dcec63e3714de5cb6a74e21a9a7e39c19ea5 Mon Sep 17 00:00:00 2001 From: sibianl Date: Fri, 7 Nov 2025 11:24:47 +0800 Subject: [PATCH 1/2] refactor(cli): prompt users to report information when connecting to relay and bootstrap public servers --- README.md | 3 +++ src/backend/main.py | 4 ++-- src/backend/server/request_handler.py | 2 +- src/parallax/cli.py | 15 +++++++++++---- src/parallax/launch.py | 2 +- src/parallax/server/node_chat_http_server.py | 2 +- src/parallax_utils/ascii_anime.py | 2 +- src/{common => parallax_utils}/file_util.py | 0 src/{common => parallax_utils}/request_metrics.py | 0 src/{common => parallax_utils}/version_check.py | 0 10 files changed, 20 insertions(+), 10 deletions(-) rename src/{common => parallax_utils}/file_util.py (100%) rename src/{common => parallax_utils}/request_metrics.py (100%) rename src/{common => parallax_utils}/version_check.py (100%) diff --git a/README.md b/README.md index 38b1fa0b..bba7dcc5 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,9 @@ Open http://localhost:3001 and you should see the setup interface. Select your desired node and model config and click continue. +> **Note:** +When running in remote mode, Parallax will use a public relay server to help establish connections between the scheduler and nodes. The public relay server will receive the IP information of both the scheduler and the nodes in order to facilitate this connection. + #### Step 3: Connect your nodes Copy the generated join command line to your node and run. For remote connection, you can find your scheduler-address in the scheduler logs. diff --git a/src/backend/main.py b/src/backend/main.py index e06d2e81..5fdb5f28 100644 --- a/src/backend/main.py +++ b/src/backend/main.py @@ -13,10 +13,10 @@ from backend.server.scheduler_manage import SchedulerManage from backend.server.server_args import parse_args from backend.server.static_config import get_model_list, get_node_join_command -from common.file_util import get_project_root -from common.version_check import check_latest_release from parallax_utils.ascii_anime import display_parallax_run +from parallax_utils.file_util import get_project_root from parallax_utils.logging_config import get_logger, set_log_level +from parallax_utils.version_check import check_latest_release app = FastAPI() diff --git a/src/backend/server/request_handler.py b/src/backend/server/request_handler.py index 094e296a..721c5a04 100644 --- a/src/backend/server/request_handler.py +++ b/src/backend/server/request_handler.py @@ -7,8 +7,8 @@ from starlette.concurrency import iterate_in_threadpool from backend.server.constants import NODE_STATUS_AVAILABLE -from common.request_metrics import get_request_metrics from parallax_utils.logging_config import get_logger +from parallax_utils.request_metrics import get_request_metrics logger = get_logger(__name__) diff --git a/src/parallax/cli.py b/src/parallax/cli.py index 29dcac13..60d1e559 100644 --- a/src/parallax/cli.py +++ b/src/parallax/cli.py @@ -18,10 +18,10 @@ import machineid import requests -from common.file_util import get_project_root -from common.version_check import get_current_version from parallax.server.server_info import HardwareInfo +from parallax_utils.file_util import get_project_root from parallax_utils.logging_config import get_logger +from parallax_utils.version_check import get_current_version logger = get_logger("parallax.cli") @@ -201,6 +201,9 @@ def run_command(args, passthrough_args: list[str] | None = None): cmd.extend(["--init-nodes-num", str(args.init_nodes_num)]) if args.use_relay: cmd.extend(_get_relay_params()) + print( + "Using public relay server to help nodes and the scheduler establish a connection (remote mode). Your IP address will be reported to the relay server to help establish the connection." + ) # Append any passthrough args (unrecognized by this CLI) directly to the command if passthrough_args: @@ -247,8 +250,10 @@ def join_command(args, passthrough_args: list[str] | None = None): if args.use_relay or ( args.scheduler_addr != "auto" and not str(args.scheduler_addr).startswith("/") ): - logger.info("Using public relay servers") cmd.extend(_get_relay_params()) + print( + "Using public relay server to help nodes and the scheduler establish a connection (remote mode). Your IP address will be reported to the relay server to help establish the connection." + ) # Append any passthrough args (unrecognized by this CLI) directly to the command if passthrough_args: @@ -279,8 +284,10 @@ def chat_command(args, passthrough_args: list[str] | None = None): if args.use_relay or ( args.scheduler_addr != "auto" and not str(args.scheduler_addr).startswith("/") ): - logger.info("Using public relay servers") cmd.extend(_get_relay_params()) + print( + "Using public relay server to help chat client and the scheduler establish a connection (remote mode). Your IP address will be reported to the relay server to help establish the connection." + ) # Append any passthrough args (unrecognized by this CLI) directly to the command if passthrough_args: diff --git a/src/parallax/launch.py b/src/parallax/launch.py index ac380e01..46f1368c 100644 --- a/src/parallax/launch.py +++ b/src/parallax/launch.py @@ -18,13 +18,13 @@ import tempfile import threading -from common.version_check import check_latest_release from parallax.p2p.server import ServerState, launch_p2p_server from parallax.server.executor import Executor from parallax.server.http_server import launch_http_server, stop_http_server from parallax.server.server_args import parse_args from parallax_utils.ascii_anime import display_parallax_join from parallax_utils.logging_config import get_logger, set_log_level +from parallax_utils.version_check import check_latest_release logger = get_logger("parallax.launch") diff --git a/src/parallax/server/node_chat_http_server.py b/src/parallax/server/node_chat_http_server.py index 43d01928..11556d83 100644 --- a/src/parallax/server/node_chat_http_server.py +++ b/src/parallax/server/node_chat_http_server.py @@ -13,7 +13,7 @@ from starlette.datastructures import State from backend.server.rpc_connection_handler import RPCConnectionHandler -from common.file_util import get_project_root +from parallax_utils.file_util import get_project_root from parallax_utils.logging_config import get_logger logger = get_logger(__name__) diff --git a/src/parallax_utils/ascii_anime.py b/src/parallax_utils/ascii_anime.py index 38eae149..680ea222 100755 --- a/src/parallax_utils/ascii_anime.py +++ b/src/parallax_utils/ascii_anime.py @@ -2,7 +2,7 @@ import math import os -from common.file_util import get_project_root +from parallax_utils.file_util import get_project_root class HexColorPrinter: diff --git a/src/common/file_util.py b/src/parallax_utils/file_util.py similarity index 100% rename from src/common/file_util.py rename to src/parallax_utils/file_util.py diff --git a/src/common/request_metrics.py b/src/parallax_utils/request_metrics.py similarity index 100% rename from src/common/request_metrics.py rename to src/parallax_utils/request_metrics.py diff --git a/src/common/version_check.py b/src/parallax_utils/version_check.py similarity index 100% rename from src/common/version_check.py rename to src/parallax_utils/version_check.py From d2be17383f6942eb71c7c8fae7ee158fa1d431ec Mon Sep 17 00:00:00 2001 From: sibianl Date: Fri, 7 Nov 2025 11:44:10 +0800 Subject: [PATCH 2/2] fix --- src/parallax/cli.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/parallax/cli.py b/src/parallax/cli.py index 60d1e559..0059d767 100644 --- a/src/parallax/cli.py +++ b/src/parallax/cli.py @@ -47,7 +47,7 @@ def check_python_version(): """Check if Python version is 3.11 or higher.""" if sys.version_info < (3, 11) or sys.version_info >= (3, 14): - print( + logger.info( f"Error: Python 3.11 or higher and less than 3.14 is required. Current version is {sys.version_info.major}.{sys.version_info.minor}." ) sys.exit(1) @@ -185,7 +185,7 @@ def run_command(args, passthrough_args: list[str] | None = None): backend_main = project_root / "src" / "backend" / "main.py" if not backend_main.exists(): - print(f"Error: Backend main.py not found at {backend_main}") + logger.info(f"Error: Backend main.py not found at {backend_main}") sys.exit(1) # Build the command to run the backend main.py @@ -201,7 +201,7 @@ def run_command(args, passthrough_args: list[str] | None = None): cmd.extend(["--init-nodes-num", str(args.init_nodes_num)]) if args.use_relay: cmd.extend(_get_relay_params()) - print( + logger.info( "Using public relay server to help nodes and the scheduler establish a connection (remote mode). Your IP address will be reported to the relay server to help establish the connection." ) @@ -223,7 +223,7 @@ def join_command(args, passthrough_args: list[str] | None = None): launch_script = project_root / "src" / "parallax" / "launch.py" if not launch_script.exists(): - print(f"Error: Launch script not found at {launch_script}") + logger.info(f"Error: Launch script not found at {launch_script}") sys.exit(1) # Set environment variable for the subprocess @@ -251,7 +251,7 @@ def join_command(args, passthrough_args: list[str] | None = None): args.scheduler_addr != "auto" and not str(args.scheduler_addr).startswith("/") ): cmd.extend(_get_relay_params()) - print( + logger.info( "Using public relay server to help nodes and the scheduler establish a connection (remote mode). Your IP address will be reported to the relay server to help establish the connection." ) @@ -271,7 +271,7 @@ def chat_command(args, passthrough_args: list[str] | None = None): launch_script = project_root / "src" / "parallax" / "launch_chat.py" if not launch_script.exists(): - print(f"Error: Launch chat script not found at {launch_script}") + logger.info(f"Error: Launch chat script not found at {launch_script}") sys.exit(1) # Build the command to run the launch_chat.py script @@ -285,7 +285,7 @@ def chat_command(args, passthrough_args: list[str] | None = None): args.scheduler_addr != "auto" and not str(args.scheduler_addr).startswith("/") ): cmd.extend(_get_relay_params()) - print( + logger.info( "Using public relay server to help chat client and the scheduler establish a connection (remote mode). Your IP address will be reported to the relay server to help establish the connection." )