@@ -2,7 +2,6 @@ package cgroups_topics_page
22
33import (
44 "fmt"
5- "github.com/charmbracelet/log"
65 "ktea/kadmin"
76 "ktea/kontext"
87 "ktea/styles"
@@ -18,6 +17,8 @@ import (
1817 "strconv"
1918 "strings"
2019
20+ "github.com/charmbracelet/log"
21+
2122 "github.com/charmbracelet/bubbles/table"
2223 tea "github.com/charmbracelet/bubbletea"
2324 lg "github.com/charmbracelet/lipgloss"
@@ -29,6 +30,7 @@ type tableFocus int
2930type state int
3031
3132const (
33+ na string = "N/A"
3234 topicFocus tableFocus = 0
3335 offsetFocus tableFocus = 1
3436
@@ -38,13 +40,16 @@ const (
3840)
3941
4042type Model struct {
43+ lister kadmin.OffsetLister
4144 tableFocus tableFocus
4245 topicsTable table.Model
4346 offsetsTable table.Model
47+ totalTable table.Model
4448 offsetsBorder * border.Model
4549 topicsBorder * border.Model
4650 topicsRows []table.Row
4751 offsetRows []table.Row
52+ totalLag int64
4853 groupName string
4954 topicByPartOffset map [string ][]partOffset
5055 cmdBar * CGroupCmdbar [string ]
@@ -63,17 +68,24 @@ func (m *Model) View(ktx *kontext.ProgramKtx, renderer *ui.Renderer) string {
6368 cmdBarView := m .cmdBar .View (ktx , renderer )
6469
6570 halfWidth := int (float64 (ktx .WindowWidth / 2 ))
66- m .topicsTable .SetHeight (ktx .AvailableHeight - 4 )
67- m .topicsTable .SetWidth (halfWidth - 2 )
71+ m .topicsTable .SetHeight (ktx .AvailableTableHeight () )
72+ m .topicsTable .SetWidth (int ( float64 ( halfWidth )) )
6873 m .topicsTable .SetColumns ([]table.Column {
69- {"Topic Name" , int (float64 (halfWidth - 4 ))},
74+ {Title : "Topic Name" , Width : int (float64 (halfWidth - 2 ))},
7075 })
7176 m .topicsTable .SetRows (m .topicsRows )
7277
73- m .offsetsTable .SetHeight (ktx .AvailableHeight - 4 )
78+ partitionColumnWidth := int (float64 (halfWidth - 4 ) * 0.22 )
79+ offsetColumnWidth := int (float64 (halfWidth - 4 ) * 0.24 )
80+ hwmColumnWidth := int (float64 (halfWidth - 4 ) * 0.24 )
81+ lagColumnWidth := int (float64 (halfWidth - 4 ) * 0.22 )
82+
83+ m .offsetsTable .SetHeight (ktx .AvailableTableHeight ())
7484 m .offsetsTable .SetColumns ([]table.Column {
75- {"Partition" , int (float64 (halfWidth - 6 ) * 0.5 )},
76- {"Offset" , int (float64 (halfWidth - 5 ) * 0.5 )},
85+ {Title : "Partition" , Width : partitionColumnWidth },
86+ {Title : "Offset" , Width : offsetColumnWidth },
87+ {Title : "High Watermark" , Width : hwmColumnWidth },
88+ {Title : "Lag" , Width : lagColumnWidth },
7789 })
7890 m .offsetsTable .SetRows (m .offsetRows )
7991
@@ -106,6 +118,24 @@ func (m *Model) View(ktx *kontext.ProgramKtx, renderer *ui.Renderer) string {
106118type partOffset struct {
107119 partition string
108120 offset int64
121+ hwm int64
122+ lag int64
123+ }
124+
125+ func (partOffset * partOffset ) getHwmValue () string {
126+ if partOffset .hwm == kadmin .ErrorValue {
127+ return na
128+ } else {
129+ return humanize .Comma (partOffset .hwm )
130+ }
131+ }
132+
133+ func (partOffset * partOffset ) getLagValue () string {
134+ if partOffset .lag == kadmin .ErrorValue {
135+ return na
136+ } else {
137+ return humanize .Comma (partOffset .lag )
138+ }
109139}
110140
111141func (m * Model ) Update (msg tea.Msg ) tea.Cmd {
@@ -122,6 +152,20 @@ func (m *Model) Update(msg tea.Msg) tea.Cmd {
122152 if ! m .cmdBar .IsFocussed () {
123153 return ui .PublishMsg (nav.LoadCGroupsPageMsg {})
124154 }
155+ case "f5" :
156+ m .state = stateOffsetsLoading
157+ return func () tea.Msg {
158+ return m .lister .ListOffsets (m .groupName )
159+ }
160+ case "tab" :
161+ // only accept when the table is focussed
162+ if ! m .cmdBar .IsFocussed () {
163+ if m .tableFocus == topicFocus {
164+ m .tableFocus = offsetFocus
165+ } else {
166+ m .tableFocus = topicFocus
167+ }
168+ }
125169 }
126170 case kadmin.OffsetListingStartedMsg :
127171 cmds = append (cmds , msg .AwaitCompletion )
@@ -144,8 +188,10 @@ func (m *Model) Update(msg tea.Msg) tea.Cmd {
144188 if ! m .cmdBar .IsFocussed () {
145189 if m .tableFocus == topicFocus {
146190 m .topicsTable , cmd = m .topicsTable .Update (msg )
191+ m .offsetsTable .GotoTop ()
147192 } else {
148193 m .offsetsTable , cmd = m .offsetsTable .Update (msg )
194+ m .totalTable .Update (msg )
149195 }
150196 if cmd != nil {
151197 cmds = append (cmds , cmd )
@@ -167,13 +213,18 @@ func (m *Model) recreateOffsetRows() {
167213
168214 selectedTopic := m .selectedRow ()
169215 if selectedTopic != "" {
216+ totalLag := int64 (0 )
170217 m .offsetRows = []table.Row {}
171218 for _ , partOffset := range m .topicByPartOffset [selectedTopic ] {
219+ totalLag += int64 (partOffset .lag )
172220 m .offsetRows = append (m .offsetRows , table.Row {
173221 partOffset .partition ,
174222 humanize .Comma (partOffset .offset ),
223+ partOffset .getHwmValue (),
224+ partOffset .getLagValue (),
175225 })
176226 }
227+ m .totalLag = totalLag
177228 sort .SliceStable (m .offsetRows , func (i , j int ) bool {
178229 a , _ := strconv .Atoi (m .offsetRows [i ][0 ])
179230 b , _ := strconv .Atoi (m .offsetRows [j ][0 ])
@@ -201,6 +252,8 @@ func (m *Model) recreateTopicRows() {
201252 partOffset := partOffset {
202253 partition : strconv .FormatInt (int64 (offset .Partition ), 10 ),
203254 offset : offset .Offset ,
255+ hwm : offset .HighWaterMark ,
256+ lag : offset .Lag ,
204257 }
205258 m .topicByPartOffset [offset .Topic ] = append (m .topicByPartOffset [offset .Topic ], partOffset )
206259 }
@@ -223,9 +276,9 @@ func (m *Model) selectedRow() string {
223276
224277func (m * Model ) Shortcuts () []statusbar.Shortcut {
225278 return []statusbar.Shortcut {
226- {"Go Back" , "esc" },
227- {"Search" , "/" },
228- {"Refresh" , "F5" },
279+ {Name : "Go Back" , Keybinding : "esc" },
280+ {Name : "Search" , Keybinding : "/" },
281+ {Name : "Refresh" , Keybinding : "F5" },
229282 }
230283}
231284
@@ -268,6 +321,7 @@ func New(lister kadmin.OffsetLister, group string) (*Model, tea.Cmd) {
268321 )
269322
270323 model := Model {
324+ lister : lister ,
271325 cmdBar : NewCGroupCmdbar [string ](
272326 cmdbar .NewSearchCmdBar ("Search groups by name" ),
273327 notifierCmdBar ,
@@ -283,7 +337,10 @@ func New(lister kadmin.OffsetLister, group string) (*Model, tea.Cmd) {
283337 border .WithTitleFn (func () string {
284338 return border .KeyValueTitle ("Total Topics" , fmt .Sprintf (" %d" , len (model .topicsRows )), true )
285339 }))
286- model .offsetsBorder = border .New (border .WithInnerPaddingTop ())
340+ model .offsetsBorder = border .New (border .WithInnerPaddingTop (),
341+ border .WithTitleFn (func () string {
342+ return border .KeyValueTitle ("Total Lag" , fmt .Sprintf (" %d" , model .totalLag ), false )
343+ }))
287344 return & model , func () tea.Msg {
288345 return lister .ListOffsets (group )
289346 }
0 commit comments