fix(cli): reduce noise & better track progress within Harmony #91
No reviewers
Labels
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: NationTech/harmony#91
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "better-cli"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Introduce a way to instrument what happens within Harmony and around Harmony (e.g. in the CLI or in Composer).
The goal is to provide visual feedback to the end users and inform them of the progress of their tasks (e.g. deployment) as clearly as possible. It is important to also let them know of the outcome of their tasks (what was created, where to access stuff, etc.).
Changes
Instrumentation architecture
Extensibility and ease of use is key here, while preserving type safety as much as possible.
The proposed API is quite simple:
Current limitations
harmony_composer
VSharmony_cli
As Harmony Composer launches commands from Harmony (CLI), they both live in different processes. And because of this, we cannot easily make all the logging happens in one place (Harmony Composer) and get rid of Harmony CLI. At least not without introducing additional complexity such as communication through a server, unix socket, etc.
So for the time being, it was decided to preserve both
harmony_composer
andharmony_cli
and let them independently log their stuff and handle their own responsibilities:harmony_composer
: takes care only of setting up & packaging a project, delegates everything else toharmony_cli
harmony_cli
: takes care of configuring & running HarmonyLogging & prompts
harmony
(core) as UI concerns shouldn't go that deepTodos
@ -13,3 +14,4 @@
#[tokio::main]
async fn main() {
env_logger::init();
let cli_logger_handle = tokio::spawn(cli_logger::init());
Ideally, this shouldn't have to be handled by the end user. But in this case, because
Maestro::initialize
prepares theTopology
(which might executeScores
), we have to register thecli_logger
early.All of this could be improved.
@johnride About this, could we actually reverse things a little bit?
As of now, when we initialize the maestro, it tries to prepare the Topology right away. But because of this, when later on we want to interpret our scores, we have to check whether the topology was actually initialized. Which might end up in a weird situation when it's not the case.
So moving the initialization inside the
Maestro::interpret
will at the same time prevent this odd temporal dependency and gives us the ability to hide thecli_logger::init
(because we can move it insideharmony_cli::init
).Another side effect is that we would be able to remove the
Maestro::new_without_initialization
and theMaestro::initialize
and keep only a bareMaestro::new
, and thus solve our naming issues 😅It's also a bit related to what we started talking together regarding the CLI pre-filtering the scores and asking the Maestro to interpret them one by one.
There me be another side effect to initializing the topology immediately : the scores we are launching from various places in the code.
They might be relying on the Topology being ready, and they don't use the maestro to interpret the score.
The conceptual idea is that we want to fail early on anything that can be checked when we launch the app. For example, checking that the topology is as expected at compile time. Let's say we compile an AWS Topology but we're not running in AWS or there is no AWS credential available, then we want to fail immediately, or at least realize this immediately and be able to react accordingly.
I agree the naming is smelly but apart from
new_without_initialize
which is a utility function that should rarely be used, it feels correct to me to instanciate the maestro with initialize so it explicitely performs its checks early on.@ -4,6 +4,9 @@ use harmony;
use harmony::{score::Score, topology::Topology};
use inquire::Confirm;
pub mod cli_logger; // FIXME: Don't make me pub
See the PR comment above (in
examples/rust/main.rs
) for more info@ -0,0 +14,4 @@
Shutdown,
}
static HARMONY_COMPOSER_EVENT_BUS: Lazy<broadcast::Sender<HarmonyComposerEvent>> =
I'm not a big fan of "duplicating" all the stuff below. It is for different concerns than the ones defined in
harmony_cli
, but it follows the same pattern.@ -138,2 +155,4 @@
None => todo!("run interactively, ask for info on CLI"),
}
instrumentation::instrument(HarmonyComposerEvent::Shutdown);
Some instrumentations are still missing, but this PR is mostly to get early feedback on the approach.
@ -186,6 +220,12 @@ async fn compile_cargo(platform: String, harmony_location: String) -> PathBuf {
.exec()
.unwrap();
let stderr = if log_enabled!(log::Level::Debug) {
cargo
prints warnings and other stuff instderr
, meaning it can get really noisy. So we'll "silence" those warnings unless we're asking for debug logs (RUST_LOG=debug
)@ -0,0 +35,4 @@
pub fn instrument(event: HarmonyEvent) -> Result<(), &'static str> {
match HARMONY_EVENT_BUS.send(event) {
Ok(_) => Ok(()),
Err(_) => Err("send error: no subscribers"),
some kind of retry mechanism could be useful here to make sure no events are lost
WIP: fix(cli): reduce noise & better track progress within Harmonyto fix(cli): reduce noise & better track progress within HarmonyOverall I have a feeling like this is too specific on each tiny little even type, it might make maintenance and extensibility quite a burden.
It's OK for now, let's go forward with this until we see a pattern emerge that will allow simplification, if ever.