From a45174393799f69aaf27cb446f8983c6db5311ce Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Fri, 16 Aug 2024 18:45:45 -0700 Subject: [PATCH] POC showing how statfile can call the conn wshclient to get file info (#242) --- cmd/server/main-server.go | 4 +++ frontend/app/store/services.ts | 4 ++- frontend/app/view/preview/preview.tsx | 10 +++++-- pkg/service/fileservice/fileservice.go | 38 ++++++++++++-------------- pkg/wshrpc/wshrpctypes.go | 2 ++ pkg/wshutil/wshrouter.go | 4 +++ pkg/wshutil/wshrpc.go | 6 ++++ 7 files changed, 44 insertions(+), 24 deletions(-) diff --git a/cmd/server/main-server.go b/cmd/server/main-server.go index 39f1ac9f7..af444d043 100644 --- a/cmd/server/main-server.go +++ b/cmd/server/main-server.go @@ -26,6 +26,8 @@ import ( "github.com/wavetermdev/thenextwave/pkg/wconfig" "github.com/wavetermdev/thenextwave/pkg/web" "github.com/wavetermdev/thenextwave/pkg/wps" + "github.com/wavetermdev/thenextwave/pkg/wshrpc" + "github.com/wavetermdev/thenextwave/pkg/wshrpc/wshremote" "github.com/wavetermdev/thenextwave/pkg/wshrpc/wshserver" "github.com/wavetermdev/thenextwave/pkg/wshutil" "github.com/wavetermdev/thenextwave/pkg/wstore" @@ -152,6 +154,8 @@ func createMainWshClient() { rpc := wshserver.GetMainRpcClient() wshutil.DefaultRouter.RegisterRoute(wshutil.DefaultRoute, rpc) wps.Broker.SetClient(wshutil.DefaultRouter) + localConnWsh := wshutil.MakeWshRpc(nil, nil, wshrpc.RpcContext{}, &wshremote.ServerImpl{}) + wshutil.DefaultRouter.RegisterRoute(wshutil.MakeConnectionRouteId(wshrpc.LocalConnName), localConnWsh) } func main() { diff --git a/frontend/app/store/services.ts b/frontend/app/store/services.ts index 1248f0034..b8a122063 100644 --- a/frontend/app/store/services.ts +++ b/frontend/app/store/services.ts @@ -74,7 +74,9 @@ class FileServiceType { SaveFile(arg1: string, arg2: string): Promise { return WOS.callBackendService("file", "SaveFile", Array.from(arguments)) } - StatFile(arg1: string): Promise { + + // get file info + StatFile(connection: string, path: string): Promise { return WOS.callBackendService("file", "StatFile", Array.from(arguments)) } } diff --git a/frontend/app/view/preview/preview.tsx b/frontend/app/view/preview/preview.tsx index 9f7edd691..83376abcf 100644 --- a/frontend/app/view/preview/preview.tsx +++ b/frontend/app/view/preview/preview.tsx @@ -44,6 +44,7 @@ export class PreviewModel implements ViewModel { isCeView: jotai.PrimitiveAtom; fileName: jotai.WritableAtom; + connection: jotai.Atom; statFile: jotai.Atom>; fullFile: jotai.Atom>; fileMimeType: jotai.Atom>; @@ -187,7 +188,6 @@ export class PreviewModel implements ViewModel { } return null; }); - this.fileName = jotai.atom( (get) => { return get(this.blockAtom)?.meta?.file; @@ -196,14 +196,18 @@ export class PreviewModel implements ViewModel { services.ObjectService.UpdateObjectMeta(`block:${blockId}`, { file: update }); } ); + this.connection = jotai.atom((get) => { + return get(this.blockAtom)?.meta?.connection; + }); this.statFile = jotai.atom>(async (get) => { const fileName = get(this.fileName); if (fileName == null) { return null; } + const conn = get(this.connection) ?? ""; // const statFile = await FileService.StatFile(fileName); - console.log("PreviewModel calling StatFile", fileName); - const statFile = await services.FileService.StatFile(fileName); + console.log("PreviewModel calling StatFile", conn, fileName); + const statFile = await services.FileService.StatFile(conn, fileName); return statFile; }); this.fullFile = jotai.atom>(async (get) => { diff --git a/pkg/service/fileservice/fileservice.go b/pkg/service/fileservice/fileservice.go index a9656644b..0b222f750 100644 --- a/pkg/service/fileservice/fileservice.go +++ b/pkg/service/fileservice/fileservice.go @@ -11,10 +11,14 @@ import ( "time" "github.com/wavetermdev/thenextwave/pkg/filestore" + "github.com/wavetermdev/thenextwave/pkg/tsgen/tsgenmeta" "github.com/wavetermdev/thenextwave/pkg/util/utilfn" "github.com/wavetermdev/thenextwave/pkg/wavebase" "github.com/wavetermdev/thenextwave/pkg/wconfig" "github.com/wavetermdev/thenextwave/pkg/wshrpc" + "github.com/wavetermdev/thenextwave/pkg/wshrpc/wshclient" + "github.com/wavetermdev/thenextwave/pkg/wshrpc/wshserver" + "github.com/wavetermdev/thenextwave/pkg/wshutil" ) const MaxFileSize = 10 * 1024 * 1024 // 10M @@ -40,30 +44,24 @@ func (fs *FileService) SaveFile(path string, data64 string) error { return nil } -func (fs *FileService) StatFile(path string) (*wshrpc.FileInfo, error) { - cleanedPath := filepath.Clean(wavebase.ExpandHomeDir(path)) - finfo, err := os.Stat(cleanedPath) - if os.IsNotExist(err) { - return &wshrpc.FileInfo{Path: wavebase.ReplaceHomeDir(path), NotFound: true}, nil +func (fs *FileService) StatFile_Meta() tsgenmeta.MethodMeta { + return tsgenmeta.MethodMeta{ + Desc: "get file info", + ArgNames: []string{"connection", "path"}, } - if err != nil { - return nil, fmt.Errorf("cannot stat file %q: %w", path, err) +} + +func (fs *FileService) StatFile(connection string, path string) (*wshrpc.FileInfo, error) { + if connection == "" { + connection = wshrpc.LocalConnName } - mimeType := utilfn.DetectMimeType(cleanedPath) - return &wshrpc.FileInfo{ - Path: cleanedPath, - Name: finfo.Name(), - Size: finfo.Size(), - Mode: finfo.Mode(), - ModeStr: finfo.Mode().String(), - ModTime: finfo.ModTime().UnixMilli(), - IsDir: finfo.IsDir(), - MimeType: mimeType, - }, nil + connRoute := wshutil.MakeConnectionRouteId(connection) + client := wshserver.GetMainRpcClient() + return wshclient.RemoteFileInfoCommand(client, path, &wshrpc.RpcOpts{Route: connRoute}) } func (fs *FileService) ReadFile(path string) (*FullFile, error) { - finfo, err := fs.StatFile(path) + finfo, err := fs.StatFile("", path) if err != nil { return nil, fmt.Errorf("cannot stat file %q: %w", path, err) } @@ -83,7 +81,7 @@ func (fs *FileService) ReadFile(path string) (*FullFile, error) { } var innerFilesInfo []wshrpc.FileInfo parent := filepath.Dir(finfo.Path) - parentFileInfo, err := fs.StatFile(parent) + parentFileInfo, err := fs.StatFile("", parent) if err == nil && parent != finfo.Path { log.Printf("adding parent") parentFileInfo.Name = ".." diff --git a/pkg/wshrpc/wshrpctypes.go b/pkg/wshrpc/wshrpctypes.go index ac7a32cd2..b635dbcb6 100644 --- a/pkg/wshrpc/wshrpctypes.go +++ b/pkg/wshrpc/wshrpctypes.go @@ -16,6 +16,8 @@ import ( "github.com/wavetermdev/thenextwave/pkg/wstore" ) +const LocalConnName = "local" + const ( RpcType_Call = "call" // single response (regular rpc) RpcType_ResponseStream = "responsestream" // stream of responses (streaming rpc) diff --git a/pkg/wshutil/wshrouter.go b/pkg/wshutil/wshrouter.go index 3c61d56cc..07413e7a3 100644 --- a/pkg/wshutil/wshrouter.go +++ b/pkg/wshutil/wshrouter.go @@ -38,6 +38,10 @@ type WshRouter struct { InputCh chan msgAndRoute } +func MakeConnectionRouteId(connId string) string { + return "conn:" + connId +} + var DefaultRouter = NewWshRouter() func NewWshRouter() *WshRouter { diff --git a/pkg/wshutil/wshrpc.go b/pkg/wshutil/wshrpc.go index b7945728f..f15b67f31 100644 --- a/pkg/wshutil/wshrpc.go +++ b/pkg/wshutil/wshrpc.go @@ -180,6 +180,12 @@ func validateServerImpl(serverImpl ServerImpl) { // closes outputCh when inputCh is closed/done func MakeWshRpc(inputCh chan []byte, outputCh chan []byte, rpcCtx wshrpc.RpcContext, serverImpl ServerImpl) *WshRpc { + if inputCh == nil { + inputCh = make(chan []byte, DefaultInputChSize) + } + if outputCh == nil { + outputCh = make(chan []byte, DefaultOutputChSize) + } validateServerImpl(serverImpl) rtn := &WshRpc{ Lock: &sync.Mutex{},