-
Notifications
You must be signed in to change notification settings - Fork 838
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
Example for two way communication with a background goroutine #1244
Comments
@mdepot This is a great idea I think! Are you working on a potential PR for this? |
Great idea. This would be really useful (and fun to make). |
I've submitted a PR that includes an example addressing the requested use case. I would greatly appreciate your insights and feedback! |
@M0hammadUsman, Thanks for your input. I also experimented with adding my own demo, but I was not happy enough with it to submit just yet. |
I experimented with some demo code of my own. In my first experiment I created goroutines completely outside of bubbletea and setup channels to communicate. But I wanted to make sure I could do a graceful shutdown, meaning if ctrl-c was hit, that bubbletea as well as all of my goroutines could each shutdown cleanly and had the chance to do any necessary cleanup functionality. In my test I used a single sync.WaitGroup around my goroutines as well as bubbletea itself, and I also used signal.Notify to create an interrupt handling context outside of bubbletea, and then passed that into NewProgram using WithContext like so: It all worked, but the end result seemed somewhat messy. Also since I had my goroutines completely outside of bubbletea, I couldn't have bubletea give feedback to the user while my goroutines were gracefully stopping, because by then Run() had already returned. I could still output to the console afterwards of course, like the "result" example does, but I felt being able to show that output from within bubbletea would be nicer. That led me to my second experiment. After finding that NewProgram could be passed tea.WithFilter(filter) I thought I would instead move my goroutines inside of bubbletea by creating them from within Init() and wrapping my sync.WaitGroup around them there. Then I would use WithFilter() to create a new Cmd that would intervene in the shutdown when QuitMsg was received, just like the "prevent-quit" example does. From there I could use that Cmd to do my graceful cleanup on ctrl-c. But of course, that still doesn't easily allow bubbletea to show the graceful shutdown status when ctrl-c is hit. This is why I was hoping for an example. There are multiple ways this could be done, but it's really not clear to me how the architects of bubbletea itself intended it to be done. On digging through the bubbletea code, I found that rather than making my own goroutines, and handling my own interrupts, wouldn't it be nice if I could just integrate my async functionality right into bubbletea using the same eventloop that bubbletea itself already uses? Bubbletea already has "channelHandlers", and they are already wrapped in a WaitGroup, and they already have the shutdown() function to cleanly terminate. Also passing Cmds around could be more integrated. My thought was that if the add() function of the channelHandlers type was exported somehow, then users of bubbletea could simply add their own channelHandlers as a way of integrating their external async code, instead of externally using their own goroutines outside of bubbletea, and then having to deal with the associated problems of coordinated signal handling and graceful shutdown separately. It would be great to hear from the architects of bubbletea on the idea of allowing this level of integration with channelHandlers. |
This is to request a new example showing two way communication between bubbletea and a background process (running as a goroutine.) There are already two examples (send-msg and realtime) which demonstrate one way communication with bubbletea, however it would seem to be a common use case to need two way communication.
For example, the background process may do some work and need to be able to push updates into the model so that the results can be displayed in the interface. But it also makes sense that the background process might want to change its behavior based on the user interacting with the interface, meaning it also needs to also be able to pull information from the model. It would be great to have an example showing this two way communication, a background goroutine that changes its behavior based on flags in the model, as well as the model being updated based on work done in the background goroutine.
The text was updated successfully, but these errors were encountered: