1
0
Fork 0
mirror of https://github.com/postmannen/ctrl.git synced 2025-03-05 06:46:48 +00:00

added tui req handler

This commit is contained in:
postmannen 2022-01-12 07:42:41 +01:00
parent 28cb3a6509
commit 7092265d8c
4 changed files with 68 additions and 13 deletions

View file

@ -26,13 +26,16 @@ type processes struct {
metrics *metrics
// Waitgroup to keep track of all the processes started
wg sync.WaitGroup
// tui
tui *tui
}
// newProcesses will prepare and return a *processes which
// is map containing all the currently running processes.
func newProcesses(ctx context.Context, metrics *metrics) *processes {
func newProcesses(ctx context.Context, metrics *metrics, tui *tui) *processes {
p := processes{
active: *newProcsMap(),
tui: tui,
}
// Prepare the parent context for the subscribers.

View file

@ -86,6 +86,8 @@ const (
// The data field is a slice of strings where the first string
// value should be the command, and the following the arguments.
REQToConsole Method = "REQToConsole"
// REQTuiToConsole
REQTuiToConsole Method = "REQTuiToConsole"
// Send text logging to some host by appending the output to a
// file, if the file do not exist we create it.
// A file with the full subject+hostName will be created on
@ -163,6 +165,9 @@ func (m Method) GetMethodsAvailable() MethodsAvailable {
REQToConsole: methodREQToConsole{
commandOrEvent: EventACK,
},
REQTuiToConsole: methodREQTuiToConsole{
commandOrEvent: EventACK,
},
REQToFileAppend: methodREQToFileAppend{
commandOrEvent: EventACK,
},
@ -212,7 +217,7 @@ func (m Method) GetMethodsAvailable() MethodsAvailable {
// the Stew client for knowing what of the req types are generally
// used as reply methods.
func (m Method) GetReplyMethods() []Method {
rm := []Method{REQToConsole, REQToFile, REQToFileAppend, REQToSocket}
rm := []Method{REQToConsole, REQTuiToConsole, REQCliCommand, REQCliCommandCont, REQToFile, REQToFileAppend, REQToSocket}
return rm
}
@ -1285,7 +1290,7 @@ func (m methodREQToConsole) getKind() CommandOrEvent {
func (m methodREQToConsole) handler(proc process, message Message, node string) ([]byte, error) {
for _, v := range message.Data {
fmt.Fprintf(os.Stdout, "%v", string(v))
fmt.Fprintf(os.Stdout, "%v", v)
}
fmt.Println()
@ -1296,6 +1301,29 @@ func (m methodREQToConsole) handler(proc process, message Message, node string)
// ---
type methodREQTuiToConsole struct {
commandOrEvent CommandOrEvent
}
func (m methodREQTuiToConsole) getKind() CommandOrEvent {
return m.commandOrEvent
}
// Handler to write directly to console.
func (m methodREQTuiToConsole) handler(proc process, message Message, node string) ([]byte, error) {
if proc.processes.tui.toConsoleCh != nil {
proc.processes.tui.toConsoleCh <- message.Data
} else {
log.Printf("error: no tui client started\n")
}
ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID))
return ackMsg, nil
}
// ---
type methodREQHttpGet struct {
commandOrEvent CommandOrEvent
}

View file

@ -142,7 +142,7 @@ func NewServer(c *Configuration, version string) (*server, error) {
nodeName: c.NodeName,
natsConn: conn,
StewardSocket: stewardSocket,
processes: newProcesses(ctx, metrics),
processes: newProcesses(ctx, metrics, tuiClient),
newMessagesCh: make(chan []subjectAndMessage),
metrics: metrics,
version: version,
@ -263,7 +263,7 @@ func (s *server) Start() {
if s.configuration.EnableTUI {
go func() {
err := s.tui.Start()
err := s.tui.Start(s.ctx, s.newMessagesCh)
if err != nil {
log.Printf("%v\n", err)
os.Exit(1)

40
tui.go
View file

@ -2,6 +2,7 @@ package steward
import (
"bufio"
"context"
"encoding/json"
"fmt"
"io/ioutil"
@ -21,10 +22,16 @@ import (
// Main structure
// ---------------------------------------------------------------------
type tui struct {
toConsoleCh chan []string
toRingbufferCh chan []subjectAndMessage
ctx context.Context
}
func newTui() (*tui, error) {
s := tui{}
ch := make(chan []string)
s := tui{
toConsoleCh: ch,
}
return &s, nil
}
@ -34,7 +41,10 @@ type slide struct {
primitive tview.Primitive
}
func (s *tui) Start() error {
func (t *tui) Start(ctx context.Context, toRingBufferCh chan []subjectAndMessage) error {
t.ctx = ctx
t.toRingbufferCh = toRingBufferCh
pages := tview.NewPages()
app := tview.NewApplication()
@ -66,9 +76,9 @@ func (s *tui) Start() error {
// chronological order, so we can auto generate the info menu with it's
// corresponding F key based on the slice index+1.
slides := []slide{
{name: "console", key: tcell.KeyF1, primitive: console(app)},
{name: "message", key: tcell.KeyF2, primitive: messageSlide(app)},
{name: "info", key: tcell.KeyF3, primitive: infoSlide(app)},
{name: "console", key: tcell.KeyF1, primitive: t.console(app)},
{name: "message", key: tcell.KeyF2, primitive: t.messageSlide(app)},
{name: "info", key: tcell.KeyF3, primitive: t.infoSlide(app)},
}
// Add a page for each slide.
@ -105,7 +115,7 @@ func (s *tui) Start() error {
// Slides
// ---------------------------------------------------------------------
func infoSlide(app *tview.Application) tview.Primitive {
func (t *tui) infoSlide(app *tview.Application) tview.Primitive {
flex := tview.NewFlex()
flex.SetTitle("info")
flex.SetBorder(true)
@ -118,7 +128,7 @@ func infoSlide(app *tview.Application) tview.Primitive {
return flex
}
func messageSlide(app *tview.Application) tview.Primitive {
func (t *tui) messageSlide(app *tview.Application) tview.Primitive {
// pageMessage is a struct for holding all the main forms and
// views used in the message slide, so we can easily reference
@ -446,7 +456,7 @@ func messageSlide(app *tview.Application) tview.Primitive {
return p.flex
}
func console(app *tview.Application) tview.Primitive {
func (t *tui) console(app *tview.Application) tview.Primitive {
// pageMessage is a struct for holding all the main forms and
// views used in the message slide, so we can easily reference
@ -532,6 +542,20 @@ func console(app *tview.Application) tview.Primitive {
// here ........
})
go func() {
for {
select {
case messageData := <-t.toConsoleCh:
for _, v := range messageData {
fmt.Fprintf(p.outputForm, "%v", v)
}
case <-t.ctx.Done():
log.Printf("info: stopped tui toConsole worker\n")
return
}
}
}()
return p.flex
}