-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
The cycleSessionStatus method performs a synchronous database operation inside the method body before returning a tea.Cmd. This blocks the UI thread while the database write completes.
Problem
Location: internal/ui/session_list.go:1160-1164
In Bubble Tea, the Update function should return quickly to keep the UI responsive. Long-running operations should be wrapped in tea.Cmd functions that execute asynchronously.
Current code:
func (sl *SessionList) cycleSessionStatus(sessionName string) tea.Cmd {
// ... get current status ...
// This blocks the UI thread!
if err := sl.sessionService.UpdateStatus(context.Background(), sessionName, nextStatus); err != nil {
logging.Logger.Error("Failed to cycle session status", "error", err)
return nil
}
// Only after blocking operation completes does this return
return func() tea.Msg {
return checkStateMsg{}
}
}Execution flow:
- User presses the status cycle key
cycleSessionStatusis called from withinUpdate()- UI freezes while
UpdateStatus()hits the database - After DB completes, function returns
- UI becomes responsive again
For SQLite on a local SSD, this might be 1-5ms (barely noticeable). But:
- Disk could be busy → 50-100ms delay
- Database lock contention → longer delays
- Future change to remote DB → significant delays
Why It Matters
- Bubble Tea's architecture assumes
Updatereturns quickly - Blocking breaks the event loop model
- Other keypresses queue up, causing input lag
- Sets a bad precedent for future code
Proposed Solution
Move the database operation into the returned command:
func (sl *SessionList) cycleSessionStatus(sessionName string) tea.Cmd {
var currentStatus *string
if sessionInfo, ok := sl.sessionState.Sessions[sessionName]; ok {
currentStatus = sessionInfo.Status
}
nextStatus := sl.statusConfig.GetNextStatus(currentStatus)
// Return a Cmd that does the DB work asynchronously
return func() tea.Msg {
if err := sl.sessionService.UpdateStatus(context.Background(), sessionName, nextStatus); err != nil {
logging.Logger.Error("Failed to cycle session status", "error", err)
// Could return an error message type for UI feedback
}
return checkStateMsg{}
}
}Now the DB operation happens in Bubble Tea's command executor, not blocking the UI.
Additional Context
Similar patterns exist in moveSelectedUp and moveSelectedDown methods which also perform synchronous DB operations. Those should be reviewed as part of this or a follow-up issue.
Labels
- enhancement
- performance