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

SPIKE: Bubble tea and two viewports #2757

Closed
JamWils opened this issue Sep 19, 2022 · 5 comments
Closed

SPIKE: Bubble tea and two viewports #2757

JamWils opened this issue Sep 19, 2022 · 5 comments
Assignees
Labels

Comments

@JamWils
Copy link
Contributor

JamWils commented Sep 19, 2022

As a user, there is a lot to see with gitops run. It is doing a lot of work in the background. There are also times I need to interact with it as I am being asked questions. I would like to have two separate view ports on the CLI. One for stdout. This should take up about 70% of the screen real estate. The second should be below that taking up about 30%.

Build a POC that leverages the bubble tea UI components to pull this off. While there are some different use-cases we want to use with the view ports for this POC let's just have the two questions we want to answer during install.

  1. Do you want to install the Weave GitOps Dashboard?
  2. To improve the product experience we would like to collect some analytics information about the app. Can we turn this feature on for the Weave GitOps Dashboard? (this should turn on Pendo)

As the user answers these questions we should see the logs continue to scroll at the top.

Key takeaways for Spike

  1. Ease of use of bubble tea and is it worth committing too?
  2. Does it improve the UX? (What about when it is used on VSCode's terminal?)
  3. Gotchas about using the library. E.g. state management is a pain, etc.

Reference

image (11)

@opudrovs
Copy link
Contributor

opudrovs commented Sep 29, 2022

@JamWils

As the user answers these questions we should see the logs continue to scroll at the top.

Sorry, I didn't quite get it, could you please clarify it? Does it mean that, when the questions are displayed, the logs are paused and continue scrolling after the questions are answered? (Is the program execution somehow paused?) Or should the logs be scrolling/the program continue its execution while the user is answering the questions?

@ozamosi
Copy link
Contributor

ozamosi commented Sep 30, 2022

Logs are running in the top uninterrupted as the question is asked in the bottom.

@opudrovs
Copy link
Contributor

opudrovs commented Oct 4, 2022

  • I've created two prototypes for this:

a) with gitops run code put into Bubble Tea completely (in the with-bubble-tea-ui branch):

gitops_run_within_bubble_tea

b) and with Bubble Tea used as a lightweight UI (in the with-lightweight-bubble-tea-ui branch):

gitops_run_with_lightweight_ui

gitops_run_with_lightweight_ui png_2

The initial branch 2757-bubble-tea-and-two-viewports contains gitops run code put into Bubble Tea but without Bubble Tea UI added yet.

Known limitations of the prototypes and Bubble Tea:

  • I've added two bubble tea viewports in the prototypes, but I have not added any inputs, because I thought the most important part was to test if the UI would work in principle in both blocking and lightweight versions, and if the Bubble Tea messages would pass through (to the UI and between different parts of the program).

Adding inputs in case of working viewports and messages should not be a technical problem.

  • The black lines on screenshots mean that in some functions or goroutines some standards output was not silenced. It's normal at the present state of the prototypes. I tried forwarding messages through a buffer but it didn't work, so messages displayed successfully in Bubble Tea UI now are all sent one by one a bubble tea messages. This should be fixable by only using bubble tea output.

  • There is a known unresolved bubble tea issue that if there is a panic in a goroutine, bubble tea does not recover the terminal properly (unlike after a panic in the main function) and the terminal stays in non-interactive mode.

Recover panics from within cmds goroutines
charmbracelet/bubbletea#234

This issue can be reproduced by pressing Ctrl+C twice (because in the prototype running the gitops run cleanup twice on Ctrl+C is not blocked) in the bubble tea regular UI branch and initial version after "Reconciliation is done" or "Portforwarding..." messages are displayed.

  • Gitops run cleanup works in the regular UI version not in the lightweight UI. I put the lightweight version together very fast. I guess it's fixable, just wanted to check if the lightweight UI version would work in principle.

  • The log messages in bottom (input) viewport are hardcoded and added to the bubble tea model when port-forwarding is set up in gitops run. So, the flow for adding the messages is real, the messages are fake.

Conclusions:

  • The aesthetic aspect of using Bubble Tea for UI looks more mature and satisfying than in case of other CLI UI golang libraries.

  • It is possible to use Bubble Tea UI with gitops run, but it will require serious investment of time and effort. Bubble Tea is very opinionated and when using it with its full capabilities in a standard/blocking fashion, the program should be split into parts which communicate via Bubble Tea messages.

It would require serious planning and rework of the program's structure (at least several days with the dev mostly frozen or new features added as separate modules) with possible future fixes for issues required.

  • If using the program with Bubble Tea UI as a non-blocking lightweight UI overlay, there can be issues with attempting to extend the UI functionality for more complex use cases and there are possibilities for unknown issues because using Bubble Tea UI in non-blocking fashion is not a standard way.

In both cases, we should keep that issue with unhandled panics in goroutines in mind, because non-operative state of the terminal would lead to very poor use experience.

  • The cheapest (LOE-wise) alternative right now is using Bubble Tea elements/screens within existing gitops run structure in a linear fashion. For example, a blocking input screen with Bubble Tea UI to ask the user questions about their preferences, then control goes back to normal gitops run flow and at the end the user needs to go through a standalone bootstrap wizard Bubble Tea screen.

@opudrovs
Copy link
Contributor

opudrovs commented Oct 10, 2022

As discussed with @ozamosi , we decided to stop on the lightweight UI option with some improvements (the dispatcher), suggested by @ozamosi with a cool diagram to boot:

if we just have 2 separate goroutines, that each do their own message processing, and then communicate to each other using messages, I think that would solve all of these problems - though the interactive scenes might move to bubbletea from the dispatcher. This would let the UI ask if the user wants to install the dashboard while the dispatcher is installing flux, and then when flux has been installed the dispatcher would find the dashboard command and just do that next.

Screenshot from 2022-10-07 12-03-08

For communication between parts (namely, for sending messages from Bubble Tea to goroutines, sending messages to the Bubble Tea UI is easier and can be performed with Bubble Tea's program.Send method) we can use channels (for unidirectional communication or two channels, one for each direction).

The "blocking stuff" is split between Bubble Tea and the dispatcher:

Anything that waits for a user in the bubbletea one, anything that waits for hard drives or networks in the dispatcher one.

About forwarding the output to Bubble Tea UI only (Bubble Tea UI is not compatible with regular fmt.Print[...] calls):

It is possible to:

  • Copy stdout
  • Send the copy to bubbletea using WithOutput
  • Close the original stdout and replace it with a pipe
  • Have a tiny goroutine or function that runs in the main loop that reads from the pipe, and sends it as a message.
  • It should work to just do os.Stdout = bytebuffer or whatever, but I'm not sure if that works for e.g. fluxexec

It's pretty much what we do with the flux binary here https://github.com/weaveworks/weave-gitops/blob/main/pkg/fluxexec/cmd_default.go#L10

The dispatcher cannot control/interact with the UI directly, the UI is displayed based on the bubble tea model. So, we'll have

a message into the UI that is a "request", and a message out of the UI that is a "response".

So, in conclusion, using Bubble Tea UI for GitOps Run looks feasible and I will be able to start working on it after #2831 is resolved.

@opudrovs
Copy link
Contributor

The UI will be implemented in #2933

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants