diff --git a/packages/tui/cmd/opencode/main.go b/packages/tui/cmd/opencode/main.go index 03be0341..73fd37ed 100644 --- a/packages/tui/cmd/opencode/main.go +++ b/packages/tui/cmd/opencode/main.go @@ -54,7 +54,9 @@ func main() { option.WithBaseURL(url), ) - apiHandler := util.NewAPILogHandler(httpClient, "tui", slog.LevelDebug) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apiHandler := util.NewAPILogHandler(ctx, httpClient, "tui", slog.LevelDebug) logger := slog.New(apiHandler) slog.SetDefault(logger) @@ -68,8 +70,6 @@ func main() { }() // Create main context for the application - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() app_, err := app.New(ctx, version, appInfo, modes, httpClient, model, prompt, mode) if err != nil { diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go index 7cb2ec40..e8859ed5 100644 --- a/packages/tui/internal/tui/tui.go +++ b/packages/tui/internal/tui/tui.go @@ -585,6 +585,8 @@ func (a appModel) openFile(filepath string) (tea.Model, tea.Cmd) { } func (a appModel) home() string { + measure := util.Measure("home.View") + defer measure() t := theme.CurrentTheme() effectiveWidth := a.width - 4 baseStyle := styles.NewStyle().Background(t.Background()) diff --git a/packages/tui/internal/util/apilogger.go b/packages/tui/internal/util/apilogger.go index b439bbec..4b872597 100644 --- a/packages/tui/internal/util/apilogger.go +++ b/packages/tui/internal/util/apilogger.go @@ -15,16 +15,32 @@ type APILogHandler struct { attrs []slog.Attr groups []string mu sync.Mutex + queue chan opencode.AppLogParams } -func NewAPILogHandler(client *opencode.Client, service string, level slog.Level) *APILogHandler { - return &APILogHandler{ +func NewAPILogHandler(ctx context.Context, client *opencode.Client, service string, level slog.Level) *APILogHandler { + result := &APILogHandler{ client: client, service: service, level: level, attrs: make([]slog.Attr, 0), groups: make([]string, 0), + queue: make(chan opencode.AppLogParams, 100_000), } + go func() { + for { + select { + case <-ctx.Done(): + return + case params := <-result.queue: + _, err := client.App.Log(context.Background(), params) + if err != nil { + slog.Error("Failed to log to API", "error", err) + } + } + } + }() + return result } func (h *APILogHandler) Enabled(_ context.Context, level slog.Level) bool { @@ -69,13 +85,7 @@ func (h *APILogHandler) Handle(ctx context.Context, r slog.Record) error { params.Extra = opencode.F(extra) } - go func() { - _, err := h.client.App.Log(context.Background(), params) - if err != nil { - // Fallback: we can't log the error using slog as it would create a loop - // TODO: fallback file? - } - }() + h.queue <- params return nil }