mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
@@ -125,6 +125,11 @@ func SetViewCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockSetViewData, opts
|
||||
return err
|
||||
}
|
||||
|
||||
// command "streamcpudata", wshserver.StreamCpuDataCommand
|
||||
func StreamCpuDataCommand(w *wshutil.WshRpc, data wshrpc.CpuDataRequest, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
|
||||
return sendRpcRequestResponseStreamHelper[wshrpc.CpuDataType](w, "streamcpudata", data, opts)
|
||||
}
|
||||
|
||||
// command "streamtest", wshserver.StreamTestCommand
|
||||
func StreamTestCommand(w *wshutil.WshRpc, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[int] {
|
||||
return sendRpcRequestResponseStreamHelper[int](w, "streamtest", nil, opts)
|
||||
|
||||
@@ -43,6 +43,7 @@ const (
|
||||
Command_EventUnsubAll = "eventunsuball"
|
||||
Command_StreamTest = "streamtest"
|
||||
Command_StreamWaveAi = "streamwaveai"
|
||||
Command_StreamCpuData = "streamcpudata"
|
||||
)
|
||||
|
||||
type RespOrErrorUnion[T any] struct {
|
||||
@@ -72,6 +73,7 @@ type WshRpcInterface interface {
|
||||
EventUnsubAllCommand(ctx context.Context) error
|
||||
StreamTestCommand(ctx context.Context) chan RespOrErrorUnion[int]
|
||||
StreamWaveAiCommand(ctx context.Context, request OpenAiStreamRequest) chan RespOrErrorUnion[OpenAIPacketType]
|
||||
StreamCpuDataCommand(ctx context.Context, request CpuDataRequest) chan RespOrErrorUnion[CpuDataType]
|
||||
}
|
||||
|
||||
// for frontend
|
||||
@@ -228,3 +230,12 @@ type OpenAIUsageType struct {
|
||||
CompletionTokens int `json:"completion_tokens,omitempty"`
|
||||
TotalTokens int `json:"total_tokens,omitempty"`
|
||||
}
|
||||
|
||||
type CpuDataRequest struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type CpuDataType struct {
|
||||
Time int64 `json:"time"`
|
||||
Value float64 `json:"value"`
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ package wshserver
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/cpu"
|
||||
"github.com/wavetermdev/thenextwave/pkg/blockcontroller"
|
||||
"github.com/wavetermdev/thenextwave/pkg/eventbus"
|
||||
"github.com/wavetermdev/thenextwave/pkg/filestore"
|
||||
@@ -67,6 +69,71 @@ func (ws *WshServer) StreamWaveAiCommand(ctx context.Context, request wshrpc.Ope
|
||||
return waveai.RunLocalCompletionStream(ctx, request)
|
||||
}
|
||||
|
||||
func (ws *WshServer) StreamCpuDataCommand(ctx context.Context, request wshrpc.CpuDataRequest) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
|
||||
rtn := make(chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType])
|
||||
go func() {
|
||||
defer close(rtn)
|
||||
MakePlotData(ctx, request.Id)
|
||||
// we can use the err from MakePlotData to determine if a routine is already running
|
||||
// but we still need a way to close it or get data from it
|
||||
for {
|
||||
now := time.Now()
|
||||
percent, err := cpu.Percent(0, false)
|
||||
if err != nil {
|
||||
rtn <- wshrpc.RespOrErrorUnion[wshrpc.CpuDataType]{Error: err}
|
||||
}
|
||||
var value float64
|
||||
if len(percent) > 0 {
|
||||
value = percent[0]
|
||||
} else {
|
||||
value = 0.0
|
||||
}
|
||||
cpuData := wshrpc.CpuDataType{Time: now.UnixMilli() / 1000, Value: value}
|
||||
rtn <- wshrpc.RespOrErrorUnion[wshrpc.CpuDataType]{Response: cpuData}
|
||||
time.Sleep(time.Second * 1)
|
||||
// this will end the goroutine if the block is closed
|
||||
err = SavePlotData(ctx, request.Id, "")
|
||||
if err != nil {
|
||||
rtn <- wshrpc.RespOrErrorUnion[wshrpc.CpuDataType]{Error: err}
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return rtn
|
||||
}
|
||||
|
||||
func MakePlotData(ctx context.Context, blockId string) error {
|
||||
block, err := wstore.DBMustGet[*wstore.Block](ctx, blockId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
viewName := block.Meta.GetString(wstore.MetaKey_View, "")
|
||||
if viewName != "cpuplot" {
|
||||
return fmt.Errorf("invalid view type: %s", viewName)
|
||||
}
|
||||
return filestore.WFS.MakeFile(ctx, blockId, "cpuplotdata", nil, filestore.FileOptsType{})
|
||||
}
|
||||
|
||||
func SavePlotData(ctx context.Context, blockId string, history string) error {
|
||||
block, err := wstore.DBMustGet[*wstore.Block](ctx, blockId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
viewName := block.Meta.GetString(wstore.MetaKey_View, "")
|
||||
if viewName != "cpuplot" {
|
||||
return fmt.Errorf("invalid view type: %s", viewName)
|
||||
}
|
||||
// todo: interpret the data being passed
|
||||
// for now, this is just to throw an error if the block was closed
|
||||
historyBytes, err := json.Marshal(history)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to serialize plot data: %v", err)
|
||||
}
|
||||
// ignore MakeFile error (already exists is ok)
|
||||
return filestore.WFS.WriteFile(ctx, blockId, "cpuplotdata", historyBytes)
|
||||
}
|
||||
|
||||
func (ws *WshServer) GetMetaCommand(ctx context.Context, data wshrpc.CommandGetMetaData) (waveobj.MetaMapType, error) {
|
||||
log.Printf("calling meta: %s\n", data.ORef)
|
||||
obj, err := wstore.DBGetORef(ctx, data.ORef)
|
||||
|
||||
Reference in New Issue
Block a user