Add daemon-managed CLI runtime and manual test lab#274
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a daemon mode for the Diode CLI, allowing it to run as a background process to manage persistent states like published ports, SOCKS proxies, and join controllers. The changes include a new daemon handler, inter-process communication via Unix sockets or Windows pipes, and a management CLI. My review identified several critical issues, including race conditions in global state management, state leakage due to incomplete global variable resets, a lack of panic recovery in connection handling, and a potential deadlock in the mode shutdown sequence.
| *config.AppConfig = cloneDaemonConfig(&daemonState.baseConfig) | ||
| resetTransientConfig(config.AppConfig) | ||
| resetRequestGlobals() |
There was a problem hiding this comment.
Overwriting the global config.AppConfig struct content and resetting request globals while a background mode (like publish or join) is active creates a significant race condition. Background goroutines belonging to the active mode rely on these global states. For example, resetRequestGlobals will clear network or dryRun settings used by a running join controller, potentially causing it to malfunction or switch networks unexpectedly during its next reconciliation loop.
There was a problem hiding this comment.
Per our discussion architecture changes:
- Start with a spec file for this feature for claude code
- Ensure to have one implementation module for changing configs. E.g. with this PR we now we have 3 options to change publishing ports 1. CLI, 2. API 3. JOIN and 3x times code duplication. It should really only be one module registering the commands and parameters into a table, and each "INTERFACE" (CLI, API, JOIN) should read the table and based on that build what it can support.
- Default behavior should be: "stay in foreground" - we still launch daemon but the CLI waits for the daemon and prints it's output. The same way
docker runworks -- Only when the user provides the-dflag should the client go to background mode. - Key question: How to manage multiple walllets? We want to also run multiple wallets as daemon as well, would we for that spawn multiple background daemons or enable the CLI to manage multiple wallets.
# Conflicts: # cmd/diode/app.go # cmd/diode/config_server.go # cmd/diode/gateway.go # cmd/diode/join.go # cmd/diode/publish.go # cmd/diode/socksd.go # cmd/diode/ssh.go # config/flag.go
|
Crash on first test: |
|
@gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a daemon-by-default architecture for the Diode client, enabling background execution of services like publish, gateway, and socksd with management via a new diode daemon command. The implementation includes cross-platform transport support (Unix sockets and Windows named pipes), attached log streaming, and a refactored output system to handle remote command execution. Feedback focuses on critical concurrency and state management issues, including a race condition in writer cleanup, missing global variable resets between requests that cause configuration leakage, and potential daemon unresponsiveness during updates. Additionally, improvements were suggested for the daemon startup specification to ensure correct flag persistence and compatibility checks.
|
@gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a background daemon architecture for the Diode client, allowing long-running commands like publish, gateway, and socksd to run persistently. By default, these commands now stay attached to the foreground to stream output, mimicking docker run behavior, but can be detached using the new -d or --detach flags. A new daemon management command has been added to inspect status, restart, or stop the background process. The implementation includes cross-platform support for IPC via Unix sockets and Windows named pipes. Feedback indicates that a block of code in the fetch command's file handling is unreachable and should be removed.
|
Issues during testing:
|
# Conflicts: # cmd/diode/app.go # cmd/diode/control_shared_test.go # cmd/diode/ssh_test.go # rpc/socks.go
|
diode ssh is broken now: |
|
As we discussed |
This pull request introduces several significant improvements to the
diodeapplication's root command handling, daemon mode management, and test coverage. The main focus is on refactoring flag registration for better maintainability, adding robust support for daemon mode lifecycle management, and introducing comprehensive unit tests for new and existing behaviors.Key changes include:
Refactoring and Flag Handling
registerRootFlagsfunction and added anewRootConfigconstructor for consistent config initialization. This improves maintainability and enables easier reuse in tests and daemon logic. (cmd/diode/app.go)-no-daemonflag to allow running the app in standalone mode, bypassing daemon management. (cmd/diode/app.go)Daemon Mode and Application Lifecycle
Diodestruct to manage daemon mode lifecycle, including mutex-protected state, mode-specific deferrals, and clean shutdown of mode-specific resources. (cmd/diode/app.go) [1] [2] [3] [4]cmd/diode/app.go) [1] [2] [3]Error Handling and Status Reporting
exitStatusErrortype for improved error reporting with custom exit codes, supporting better CLI feedback and integration. (cmd/diode/cli_status.go)Daemon Mode Configuration and Hot Reload
cmd/diode/config_server.go)Testing and Reliability
cmd/diode/daemon_test.go)These changes collectively improve the robustness, maintainability, and testability of the application's root command and daemon management infrastructure.