- 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
+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)