mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
wsh routing + proxy (#224)
lots of changes, including: * source/route to rpcmessage * rpcproxy * wshrouter * bug fixing * wps uses routeids not clients
This commit is contained in:
@@ -12,147 +12,147 @@ import (
|
||||
)
|
||||
|
||||
// command "authenticate", wshserver.AuthenticateCommand
|
||||
func AuthenticateCommand(w *wshutil.WshRpc, data string, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func AuthenticateCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "authenticate", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "controllerinput", wshserver.ControllerInputCommand
|
||||
func ControllerInputCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockInputData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func ControllerInputCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockInputData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "controllerinput", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "controllerrestart", wshserver.ControllerRestartCommand
|
||||
func ControllerRestartCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockRestartData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func ControllerRestartCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockRestartData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "controllerrestart", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "createblock", wshserver.CreateBlockCommand
|
||||
func CreateBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandCreateBlockData, opts *wshrpc.WshRpcCommandOpts) (waveobj.ORef, error) {
|
||||
func CreateBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandCreateBlockData, opts *wshrpc.RpcOpts) (waveobj.ORef, error) {
|
||||
resp, err := sendRpcRequestCallHelper[waveobj.ORef](w, "createblock", data, opts)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// command "deleteblock", wshserver.DeleteBlockCommand
|
||||
func DeleteBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandDeleteBlockData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func DeleteBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandDeleteBlockData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "deleteblock", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "eventpublish", wshserver.EventPublishCommand
|
||||
func EventPublishCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func EventPublishCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "eventpublish", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "eventrecv", wshserver.EventRecvCommand
|
||||
func EventRecvCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func EventRecvCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "eventrecv", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "eventsub", wshserver.EventSubCommand
|
||||
func EventSubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func EventSubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "eventsub", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "eventunsub", wshserver.EventUnsubCommand
|
||||
func EventUnsubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func EventUnsubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "eventunsub", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "eventunsuball", wshserver.EventUnsubAllCommand
|
||||
func EventUnsubAllCommand(w *wshutil.WshRpc, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func EventUnsubAllCommand(w *wshutil.WshRpc, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "eventunsuball", nil, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "fileappend", wshserver.FileAppendCommand
|
||||
func FileAppendCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func FileAppendCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "fileappend", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "fileappendijson", wshserver.FileAppendIJsonCommand
|
||||
func FileAppendIJsonCommand(w *wshutil.WshRpc, data wshrpc.CommandAppendIJsonData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func FileAppendIJsonCommand(w *wshutil.WshRpc, data wshrpc.CommandAppendIJsonData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "fileappendijson", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "fileread", wshserver.FileReadCommand
|
||||
func FileReadCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.WshRpcCommandOpts) (string, error) {
|
||||
func FileReadCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.RpcOpts) (string, error) {
|
||||
resp, err := sendRpcRequestCallHelper[string](w, "fileread", data, opts)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// command "filewrite", wshserver.FileWriteCommand
|
||||
func FileWriteCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func FileWriteCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "filewrite", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "getmeta", wshserver.GetMetaCommand
|
||||
func GetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandGetMetaData, opts *wshrpc.WshRpcCommandOpts) (waveobj.MetaMapType, error) {
|
||||
func GetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandGetMetaData, opts *wshrpc.RpcOpts) (waveobj.MetaMapType, error) {
|
||||
resp, err := sendRpcRequestCallHelper[waveobj.MetaMapType](w, "getmeta", data, opts)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// command "message", wshserver.MessageCommand
|
||||
func MessageCommand(w *wshutil.WshRpc, data wshrpc.CommandMessageData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func MessageCommand(w *wshutil.WshRpc, data wshrpc.CommandMessageData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "message", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "remotefileinfo", wshserver.RemoteFileInfoCommand
|
||||
func RemoteFileInfoCommand(w *wshutil.WshRpc, data string, opts *wshrpc.WshRpcCommandOpts) (*wshrpc.FileInfo, error) {
|
||||
func RemoteFileInfoCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) (*wshrpc.FileInfo, error) {
|
||||
resp, err := sendRpcRequestCallHelper[*wshrpc.FileInfo](w, "remotefileinfo", data, opts)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// command "remotestreamfile", wshserver.RemoteStreamFileCommand
|
||||
func RemoteStreamFileCommand(w *wshutil.WshRpc, data wshrpc.CommandRemoteStreamFileData, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteStreamFileRtnData] {
|
||||
func RemoteStreamFileCommand(w *wshutil.WshRpc, data wshrpc.CommandRemoteStreamFileData, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteStreamFileRtnData] {
|
||||
return sendRpcRequestResponseStreamHelper[wshrpc.CommandRemoteStreamFileRtnData](w, "remotestreamfile", data, opts)
|
||||
}
|
||||
|
||||
// command "resolveids", wshserver.ResolveIdsCommand
|
||||
func ResolveIdsCommand(w *wshutil.WshRpc, data wshrpc.CommandResolveIdsData, opts *wshrpc.WshRpcCommandOpts) (wshrpc.CommandResolveIdsRtnData, error) {
|
||||
func ResolveIdsCommand(w *wshutil.WshRpc, data wshrpc.CommandResolveIdsData, opts *wshrpc.RpcOpts) (wshrpc.CommandResolveIdsRtnData, error) {
|
||||
resp, err := sendRpcRequestCallHelper[wshrpc.CommandResolveIdsRtnData](w, "resolveids", data, opts)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// command "setmeta", wshserver.SetMetaCommand
|
||||
func SetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandSetMetaData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func SetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandSetMetaData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "setmeta", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "setview", wshserver.SetViewCommand
|
||||
func SetViewCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockSetViewData, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func SetViewCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockSetViewData, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "setview", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
// command "streamcpudata", wshserver.StreamCpuDataCommand
|
||||
func StreamCpuDataCommand(w *wshutil.WshRpc, data wshrpc.CpuDataRequest, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
|
||||
func StreamCpuDataCommand(w *wshutil.WshRpc, data wshrpc.CpuDataRequest, opts *wshrpc.RpcOpts) 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] {
|
||||
func StreamTestCommand(w *wshutil.WshRpc, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[int] {
|
||||
return sendRpcRequestResponseStreamHelper[int](w, "streamtest", nil, opts)
|
||||
}
|
||||
|
||||
// command "streamwaveai", wshserver.StreamWaveAiCommand
|
||||
func StreamWaveAiCommand(w *wshutil.WshRpc, data wshrpc.OpenAiStreamRequest, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType] {
|
||||
func StreamWaveAiCommand(w *wshutil.WshRpc, data wshrpc.OpenAiStreamRequest, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType] {
|
||||
return sendRpcRequestResponseStreamHelper[wshrpc.OpenAIPacketType](w, "streamwaveai", data, opts)
|
||||
}
|
||||
|
||||
// command "test", wshserver.TestCommand
|
||||
func TestCommand(w *wshutil.WshRpc, data string, opts *wshrpc.WshRpcCommandOpts) error {
|
||||
func TestCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) error {
|
||||
_, err := sendRpcRequestCallHelper[any](w, "test", data, opts)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,19 +9,19 @@ import (
|
||||
"github.com/wavetermdev/thenextwave/pkg/wshutil"
|
||||
)
|
||||
|
||||
func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.WshRpcCommandOpts) (T, error) {
|
||||
func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.RpcOpts) (T, error) {
|
||||
if opts == nil {
|
||||
opts = &wshrpc.WshRpcCommandOpts{}
|
||||
opts = &wshrpc.RpcOpts{}
|
||||
}
|
||||
var respData T
|
||||
if opts.NoResponse {
|
||||
err := w.SendCommand(command, data)
|
||||
err := w.SendCommand(command, data, opts)
|
||||
if err != nil {
|
||||
return respData, err
|
||||
}
|
||||
return respData, nil
|
||||
}
|
||||
resp, err := w.SendRpcRequest(command, data, opts.Timeout)
|
||||
resp, err := w.SendRpcRequest(command, data, opts)
|
||||
if err != nil {
|
||||
return respData, err
|
||||
}
|
||||
@@ -32,12 +32,12 @@ func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data int
|
||||
return respData, nil
|
||||
}
|
||||
|
||||
func sendRpcRequestResponseStreamHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[T] {
|
||||
func sendRpcRequestResponseStreamHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[T] {
|
||||
if opts == nil {
|
||||
opts = &wshrpc.WshRpcCommandOpts{}
|
||||
opts = &wshrpc.RpcOpts{}
|
||||
}
|
||||
respChan := make(chan wshrpc.RespOrErrorUnion[T])
|
||||
reqHandler, err := w.SendComplexRequest(command, data, true, opts.Timeout)
|
||||
reqHandler, err := w.SendComplexRequest(command, data, opts)
|
||||
if err != nil {
|
||||
go func() {
|
||||
respChan <- wshrpc.RespOrErrorUnion[T]{Error: err}
|
||||
|
||||
@@ -6,6 +6,7 @@ package wshrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
@@ -57,6 +58,7 @@ type RespOrErrorUnion[T any] struct {
|
||||
|
||||
type WshRpcInterface interface {
|
||||
AuthenticateCommand(ctx context.Context, data string) error
|
||||
|
||||
MessageCommand(ctx context.Context, data CommandMessageData) error
|
||||
GetMetaCommand(ctx context.Context, data CommandGetMetaData) (wstore.MetaMapType, error)
|
||||
SetMetaCommand(ctx context.Context, data CommandSetMetaData) error
|
||||
@@ -90,15 +92,15 @@ type WshServerCommandMeta struct {
|
||||
CommandType string `json:"commandtype"`
|
||||
}
|
||||
|
||||
type WshRpcCommandOpts struct {
|
||||
Timeout int `json:"timeout"`
|
||||
NoResponse bool `json:"noresponse"`
|
||||
type RpcOpts struct {
|
||||
Timeout int `json:"timeout,omitempty"`
|
||||
NoResponse bool `json:"noresponse,omitempty"`
|
||||
Route string `json:"route,omitempty"`
|
||||
}
|
||||
|
||||
type RpcContext struct {
|
||||
BlockId string `json:"blockid,omitempty"`
|
||||
TabId string `json:"tabid,omitempty"`
|
||||
WindowId string `json:"windowid,omitempty"`
|
||||
BlockId string `json:"blockid,omitempty"`
|
||||
TabId string `json:"tabid,omitempty"`
|
||||
}
|
||||
|
||||
func HackRpcContextIntoData(dataPtr any, rpcContext RpcContext) {
|
||||
@@ -122,12 +124,12 @@ func HackRpcContextIntoData(dataPtr any, rpcContext RpcContext) {
|
||||
field.SetString(rpcContext.BlockId)
|
||||
case "TabId":
|
||||
field.SetString(rpcContext.TabId)
|
||||
case "WindowId":
|
||||
field.SetString(rpcContext.WindowId)
|
||||
case "BlockORef":
|
||||
if rpcContext.BlockId != "" {
|
||||
field.Set(reflect.ValueOf(waveobj.MakeORef(wstore.OType_Block, rpcContext.BlockId)))
|
||||
}
|
||||
default:
|
||||
log.Printf("invalid wshcontext tag: %q in type(%T)", tag, dataPtr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +149,8 @@ type CommandSetMetaData struct {
|
||||
}
|
||||
|
||||
type CommandResolveIdsData struct {
|
||||
Ids []string `json:"ids"`
|
||||
BlockId string `json:"blockid" wshcontext:"BlockId"`
|
||||
Ids []string `json:"ids"`
|
||||
}
|
||||
|
||||
type CommandResolveIdsRtnData struct {
|
||||
|
||||
@@ -30,26 +30,33 @@ import (
|
||||
|
||||
const SimpleId_This = "this"
|
||||
|
||||
type WshServer struct{}
|
||||
|
||||
func (*WshServer) WshServerImpl() {}
|
||||
|
||||
var WshServerImpl = WshServer{}
|
||||
|
||||
func (ws *WshServer) TestCommand(ctx context.Context, data string) error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("panic in TestCommand: %v", r)
|
||||
}
|
||||
}()
|
||||
rpc := wshutil.GetWshRpcFromContext(ctx)
|
||||
if rpc == nil {
|
||||
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
|
||||
log.Printf("TEST src:%s | %s\n", rpcSource, data)
|
||||
if rpcSource == "" {
|
||||
return nil
|
||||
}
|
||||
go func() {
|
||||
wshclient.MessageCommand(rpc, wshrpc.CommandMessageData{Message: "test message"}, &wshrpc.WshRpcCommandOpts{NoResponse: true})
|
||||
resp, err := wshclient.RemoteFileInfoCommand(rpc, "~/work/wails/thenextwave/README.md", nil)
|
||||
mainClient := GetMainRpcClient()
|
||||
wshclient.MessageCommand(mainClient, wshrpc.CommandMessageData{Message: "test message"}, &wshrpc.RpcOpts{NoResponse: true, Route: rpcSource})
|
||||
resp, err := wshclient.RemoteFileInfoCommand(mainClient, "~/work/wails/thenextwave/README.md", &wshrpc.RpcOpts{Route: rpcSource})
|
||||
if err != nil {
|
||||
log.Printf("error getting remote file info: %v", err)
|
||||
return
|
||||
}
|
||||
log.Printf("remote file info: %#v\n", resp)
|
||||
|
||||
rch := wshclient.RemoteStreamFileCommand(rpc, wshrpc.CommandRemoteStreamFileData{Path: "~/work/wails/thenextwave/README.md"}, nil)
|
||||
rch := wshclient.RemoteStreamFileCommand(mainClient, wshrpc.CommandRemoteStreamFileData{Path: "~/work/wails/thenextwave/README.md"}, &wshrpc.RpcOpts{Route: rpcSource})
|
||||
for msg := range rch {
|
||||
if msg.Error != nil {
|
||||
log.Printf("error in stream: %v", msg.Error)
|
||||
@@ -66,22 +73,6 @@ func (ws *WshServer) TestCommand(ctx context.Context, data string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *WshServer) AuthenticateCommand(ctx context.Context, data string) error {
|
||||
w := wshutil.GetWshRpcFromContext(ctx)
|
||||
if w == nil {
|
||||
return fmt.Errorf("no wshrpc in context")
|
||||
}
|
||||
newCtx, err := wshutil.ValidateAndExtractRpcContextFromToken(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error validating token: %w", err)
|
||||
}
|
||||
if newCtx == nil {
|
||||
return fmt.Errorf("no context found in jwt token")
|
||||
}
|
||||
w.SetRpcContext(*newCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
// for testing
|
||||
func (ws *WshServer) MessageCommand(ctx context.Context, data wshrpc.CommandMessageData) error {
|
||||
log.Printf("MESSAGE: %s | %q\n", data.ORef, data.Message)
|
||||
@@ -228,17 +219,12 @@ func sendWaveObjUpdate(oref waveobj.ORef) {
|
||||
})
|
||||
}
|
||||
|
||||
func resolveSimpleId(ctx context.Context, simpleId string) (*waveobj.ORef, error) {
|
||||
func resolveSimpleId(ctx context.Context, data wshrpc.CommandResolveIdsData, simpleId string) (*waveobj.ORef, error) {
|
||||
if simpleId == SimpleId_This {
|
||||
wshRpc := wshutil.GetWshRpcFromContext(ctx)
|
||||
if wshRpc == nil {
|
||||
return nil, fmt.Errorf("no wshrpc in context")
|
||||
if data.BlockId == "" {
|
||||
return nil, fmt.Errorf("no blockid in request")
|
||||
}
|
||||
rpcCtx := wshRpc.GetRpcContext()
|
||||
if rpcCtx.BlockId == "" {
|
||||
return nil, fmt.Errorf("no blockid in rpc context")
|
||||
}
|
||||
return &waveobj.ORef{OType: wstore.OType_Block, OID: rpcCtx.BlockId}, nil
|
||||
return &waveobj.ORef{OType: wstore.OType_Block, OID: data.BlockId}, nil
|
||||
}
|
||||
if strings.Contains(simpleId, ":") {
|
||||
rtn, err := waveobj.ParseORef(simpleId)
|
||||
@@ -254,7 +240,7 @@ func (ws *WshServer) ResolveIdsCommand(ctx context.Context, data wshrpc.CommandR
|
||||
rtn := wshrpc.CommandResolveIdsRtnData{}
|
||||
rtn.ResolvedIds = make(map[string]waveobj.ORef)
|
||||
for _, simpleId := range data.Ids {
|
||||
oref, err := resolveSimpleId(ctx, simpleId)
|
||||
oref, err := resolveSimpleId(ctx, data, simpleId)
|
||||
if err != nil || oref == nil {
|
||||
continue
|
||||
}
|
||||
@@ -471,40 +457,40 @@ func (ws *WshServer) EventRecvCommand(ctx context.Context, data wshrpc.WaveEvent
|
||||
}
|
||||
|
||||
func (ws *WshServer) EventPublishCommand(ctx context.Context, data wshrpc.WaveEvent) error {
|
||||
wrpc := wshutil.GetWshRpcFromContext(ctx)
|
||||
if wrpc == nil {
|
||||
return fmt.Errorf("no wshrpc in context")
|
||||
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
|
||||
if rpcSource == "" {
|
||||
return fmt.Errorf("no rpc source set")
|
||||
}
|
||||
if data.Sender == "" {
|
||||
data.Sender = wrpc.ClientId()
|
||||
data.Sender = rpcSource
|
||||
}
|
||||
wps.Broker.Publish(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *WshServer) EventSubCommand(ctx context.Context, data wshrpc.SubscriptionRequest) error {
|
||||
wrpc := wshutil.GetWshRpcFromContext(ctx)
|
||||
if wrpc == nil {
|
||||
return fmt.Errorf("no wshrpc in context")
|
||||
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
|
||||
if rpcSource == "" {
|
||||
return fmt.Errorf("no rpc source set")
|
||||
}
|
||||
wps.Broker.Subscribe(wrpc, data)
|
||||
wps.Broker.Subscribe(rpcSource, data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *WshServer) EventUnsubCommand(ctx context.Context, data wshrpc.SubscriptionRequest) error {
|
||||
wrpc := wshutil.GetWshRpcFromContext(ctx)
|
||||
if wrpc == nil {
|
||||
return fmt.Errorf("no wshrpc in context")
|
||||
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
|
||||
if rpcSource == "" {
|
||||
return fmt.Errorf("no rpc source set")
|
||||
}
|
||||
wps.Broker.Unsubscribe(wrpc, data)
|
||||
wps.Broker.Unsubscribe(rpcSource, data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *WshServer) EventUnsubAllCommand(ctx context.Context) error {
|
||||
wrpc := wshutil.GetWshRpcFromContext(ctx)
|
||||
if wrpc == nil {
|
||||
return fmt.Errorf("no wshrpc in context")
|
||||
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
|
||||
if rpcSource == "" {
|
||||
return fmt.Errorf("no rpc source set")
|
||||
}
|
||||
wps.Broker.UnsubscribeAll(wrpc)
|
||||
wps.Broker.UnsubscribeAll(rpcSource)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,89 +4,42 @@
|
||||
package wshserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/wavetermdev/thenextwave/pkg/wshrpc"
|
||||
"github.com/wavetermdev/thenextwave/pkg/wshutil"
|
||||
)
|
||||
|
||||
// this file contains the generic types and functions that create and power the WSH server
|
||||
|
||||
const (
|
||||
DefaultOutputChSize = 32
|
||||
DefaultInputChSize = 32
|
||||
)
|
||||
|
||||
type WshServer struct{}
|
||||
|
||||
func (*WshServer) WshServerImpl() {}
|
||||
|
||||
type WshServerMethodDecl struct {
|
||||
Command string
|
||||
CommandType string
|
||||
MethodName string
|
||||
Method reflect.Value
|
||||
CommandDataType reflect.Type
|
||||
DefaultResponseDataType reflect.Type
|
||||
RequestDataTypes []reflect.Type // for streaming requests
|
||||
ResponseDataTypes []reflect.Type // for streaming responses
|
||||
}
|
||||
|
||||
var WshServerImpl = WshServer{}
|
||||
var contextRType = reflect.TypeOf((*context.Context)(nil)).Elem()
|
||||
var wshCommandDeclMap = wshrpc.GenerateWshCommandDeclMap()
|
||||
|
||||
func GetWshServerMethod(command string, commandType string, methodName string, methodFunc any) *WshServerMethodDecl {
|
||||
methodVal := reflect.ValueOf(methodFunc)
|
||||
methodType := methodVal.Type()
|
||||
if methodType.Kind() != reflect.Func {
|
||||
panic(fmt.Sprintf("methodVal must be a function got [%v]", methodType))
|
||||
}
|
||||
if methodType.In(0) != contextRType {
|
||||
panic(fmt.Sprintf("methodVal must have a context as the first argument %v", methodType))
|
||||
}
|
||||
var defResponseType reflect.Type
|
||||
if methodType.NumOut() > 1 {
|
||||
defResponseType = methodType.Out(0)
|
||||
}
|
||||
var cdataType reflect.Type
|
||||
if methodType.NumIn() > 1 {
|
||||
cdataType = methodType.In(1)
|
||||
}
|
||||
rtn := &WshServerMethodDecl{
|
||||
Command: command,
|
||||
CommandType: commandType,
|
||||
MethodName: methodName,
|
||||
Method: methodVal,
|
||||
CommandDataType: cdataType,
|
||||
DefaultResponseDataType: defResponseType,
|
||||
}
|
||||
return rtn
|
||||
}
|
||||
|
||||
func decodeRtnVals(rtnVals []reflect.Value) (any, error) {
|
||||
switch len(rtnVals) {
|
||||
case 0:
|
||||
return nil, nil
|
||||
case 1:
|
||||
errIf := rtnVals[0].Interface()
|
||||
if errIf == nil {
|
||||
return nil, nil
|
||||
func handleDomainSocketClient(conn net.Conn) {
|
||||
proxy := wshutil.MakeRpcProxy()
|
||||
go func() {
|
||||
writeErr := wshutil.AdaptOutputChToStream(proxy.ToRemoteCh, conn)
|
||||
if writeErr != nil {
|
||||
log.Printf("error writing to domain socket: %v\n", writeErr)
|
||||
}
|
||||
return nil, errIf.(error)
|
||||
case 2:
|
||||
errIf := rtnVals[1].Interface()
|
||||
if errIf == nil {
|
||||
return rtnVals[0].Interface(), nil
|
||||
}
|
||||
return rtnVals[0].Interface(), errIf.(error)
|
||||
default:
|
||||
return nil, fmt.Errorf("too many return values: %d", len(rtnVals))
|
||||
}()
|
||||
go func() {
|
||||
// when input is closed, close the connection
|
||||
defer conn.Close()
|
||||
wshutil.AdaptStreamToMsgCh(conn, proxy.FromRemoteCh)
|
||||
}()
|
||||
rpcCtx, err := proxy.HandleAuthentication()
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
log.Printf("error handling authentication: %v\n", err)
|
||||
return
|
||||
}
|
||||
// now that we're authenticated, set the ctx and attach to the router
|
||||
log.Printf("domain socket connection authenticated: %#v\n", rpcCtx)
|
||||
proxy.SetRpcContext(rpcCtx)
|
||||
wshutil.DefaultRouter.RegisterRoute("controller:"+rpcCtx.BlockId, proxy)
|
||||
}
|
||||
|
||||
func RunWshRpcOverListener(listener net.Listener) {
|
||||
@@ -98,11 +51,19 @@ func RunWshRpcOverListener(listener net.Listener) {
|
||||
continue
|
||||
}
|
||||
log.Print("got domain socket connection\n")
|
||||
// TODO deal with closing connection
|
||||
go wshutil.SetupConnRpcClient(conn, &WshServerImpl)
|
||||
go handleDomainSocketClient(conn)
|
||||
}
|
||||
}
|
||||
|
||||
func MakeWshServer(inputCh chan []byte, outputCh chan []byte, initialCtx wshrpc.RpcContext) {
|
||||
wshutil.MakeWshRpc(inputCh, outputCh, initialCtx, &WshServerImpl)
|
||||
var waveSrvClient_Singleton *wshutil.WshRpc
|
||||
var waveSrvClient_Once = &sync.Once{}
|
||||
|
||||
// returns the wavesrv main rpc client singleton
|
||||
func GetMainRpcClient() *wshutil.WshRpc {
|
||||
waveSrvClient_Once.Do(func() {
|
||||
inputCh := make(chan []byte, DefaultInputChSize)
|
||||
outputCh := make(chan []byte, DefaultOutputChSize)
|
||||
waveSrvClient_Singleton = wshutil.MakeWshRpc(inputCh, outputCh, wshrpc.RpcContext{}, &WshServerImpl)
|
||||
})
|
||||
return waveSrvClient_Singleton
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user