repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
0331923
parent
36f1b93
author
Eric Bower
date
2024-10-06 18:27:23 +0000 UTC
fix(pico): cleanup logs when leaving page
2 files changed,  +42, -10
M Makefile
+4, -0
 1@@ -24,6 +24,10 @@ lint:
 2 	golangci-lint run -E goimports -E godot --timeout 10m
 3 .PHONY: lint
 4 
 5+test:
 6+	go test ./...
 7+.PHONY: test
 8+
 9 bp-setup:
10 	$(DOCKER_CMD) buildx ls | grep pico || $(DOCKER_CMD) buildx create --name pico
11 	$(DOCKER_CMD) buildx use pico
M tui/logs/logs.go
+38, -10
  1@@ -2,6 +2,7 @@ package logs
  2 
  3 import (
  4 	"bufio"
  5+	"context"
  6 	"encoding/json"
  7 	"fmt"
  8 	"strings"
  9@@ -23,6 +24,7 @@ const (
 10 )
 11 
 12 type logLineLoadedMsg map[string]any
 13+type errMsg error
 14 
 15 type Model struct {
 16 	shared   common.SharedModel
 17@@ -31,6 +33,9 @@ type Model struct {
 18 	viewport viewport.Model
 19 	input    input.Model
 20 	sub      chan map[string]any
 21+	ctx      context.Context
 22+	done     context.CancelFunc
 23+	errMsg   error
 24 }
 25 
 26 func headerHeight(shrd common.SharedModel) int {
 27@@ -59,20 +64,24 @@ func NewModel(shrd common.SharedModel) Model {
 28 	viewport.YPosition = hh
 29 	viewport.SetContent(defMsg)
 30 
 31+	ctx, cancel := context.WithCancel(shrd.Session.Context())
 32+
 33 	return Model{
 34 		shared:   shrd,
 35-		state:    stateReady,
 36+		state:    stateLoading,
 37 		viewport: viewport,
 38 		logData:  []map[string]any{},
 39 		input:    im,
 40 		sub:      make(chan map[string]any),
 41+		ctx:      ctx,
 42+		done:     cancel,
 43 	}
 44 }
 45 
 46 func (m Model) Init() tea.Cmd {
 47 	return tea.Batch(
 48 		m.connectLogs(m.sub),
 49-		waitForActivity(m.sub),
 50+		m.waitForActivity(m.sub),
 51 	)
 52 }
 53 
 54@@ -86,7 +95,9 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 55 		hh := headerHeight(m.shared)
 56 		m.viewport.Height = msg.Height - hh - inputHeight
 57 		m.viewport.SetContent(logsToStr(m.shared.Styles, m.logData, m.input.Value()))
 58+
 59 	case logLineLoadedMsg:
 60+		m.state = stateReady
 61 		m.logData = append(m.logData, msg)
 62 		lng := len(m.logData)
 63 		if lng > 1000 {
 64@@ -100,7 +111,18 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 65 		if wasAt {
 66 			m.viewport.GotoBottom()
 67 		}
 68-		cmds = append(cmds, waitForActivity(m.sub))
 69+		cmds = append(cmds, m.waitForActivity(m.sub))
 70+
 71+	case errMsg:
 72+		m.errMsg = msg
 73+
 74+	case pages.NavigateMsg:
 75+		// cancel activity logger
 76+		m.done()
 77+		// reset model
 78+		next := NewModel(m.shared)
 79+		return next, nil
 80+
 81 	case tea.KeyMsg:
 82 		switch msg.String() {
 83 		case "q", "esc":
 84@@ -124,25 +146,31 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 85 }
 86 
 87 func (m Model) View() string {
 88+	if m.errMsg != nil {
 89+		return m.shared.Styles.Error.Render(m.errMsg.Error())
 90+	}
 91 	if m.state == stateLoading {
 92-		return "Loading ..."
 93+		return defMsg
 94 	}
 95 	return m.viewport.View() + "\n" + m.input.View()
 96 }
 97 
 98-func waitForActivity(sub chan map[string]any) tea.Cmd {
 99+func (m Model) waitForActivity(sub chan map[string]any) tea.Cmd {
100 	return func() tea.Msg {
101-		result := <-sub
102-		return logLineLoadedMsg(result)
103+		select {
104+		case result := <-sub:
105+			return logLineLoadedMsg(result)
106+		case <-m.ctx.Done():
107+			return nil
108+		}
109 	}
110 }
111 
112 func (m Model) connectLogs(sub chan map[string]any) tea.Cmd {
113 	return func() tea.Msg {
114-		stdoutPipe, err := shared.ConnectToLogs(m.shared.Session.Context())
115+		stdoutPipe, err := shared.ConnectToLogs(m.ctx)
116 		if err != nil {
117-			fmt.Println(err)
118-			return nil
119+			return errMsg(err)
120 		}
121 
122 		scanner := bufio.NewScanner(stdoutPipe)