From f3383d184762673869fe4ef6327188ee0019786a Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 20 May 2024 15:57:15 -0700 Subject: [PATCH] new wstore package, move core types to there. create a syncmap --- pkg/blockcontroller/blockcontroller.go | 80 +++--------------------- pkg/service/blockservice/blockservice.go | 7 ++- pkg/util/ds/syncmap.go | 43 +++++++++++++ pkg/wstore/wstore.go | 68 ++++++++++++++++++++ 4 files changed, 125 insertions(+), 73 deletions(-) create mode 100644 pkg/util/ds/syncmap.go create mode 100644 pkg/wstore/wstore.go diff --git a/pkg/blockcontroller/blockcontroller.go b/pkg/blockcontroller/blockcontroller.go index 8bb9c663..53ccded9 100644 --- a/pkg/blockcontroller/blockcontroller.go +++ b/pkg/blockcontroller/blockcontroller.go @@ -16,6 +16,7 @@ import ( "github.com/wailsapp/wails/v3/pkg/application" "github.com/wavetermdev/thenextwave/pkg/eventbus" "github.com/wavetermdev/thenextwave/pkg/shellexec" + "github.com/wavetermdev/thenextwave/pkg/wstore" ) const ( @@ -25,48 +26,11 @@ const ( var globalLock = &sync.Mutex{} var blockControllerMap = make(map[string]*BlockController) -var blockDataMap = make(map[string]*BlockData) - -type BlockData struct { - Lock *sync.Mutex `json:"-"` - BlockId string `json:"blockid"` - BlockDef *BlockDef `json:"blockdef"` - Controller string `json:"controller"` - ControllerStatus string `json:"controllerstatus"` - View string `json:"view"` - Meta map[string]any `json:"meta,omitempty"` - RuntimeOpts *RuntimeOpts `json:"runtimeopts,omitempty"` -} - -type FileDef struct { - FileType string `json:"filetype,omitempty"` - Path string `json:"path,omitempty"` - Url string `json:"url,omitempty"` - Content string `json:"content,omitempty"` - Meta map[string]any `json:"meta,omitempty"` -} - -type BlockDef struct { - Controller string `json:"controller"` - View string `json:"view,omitempty"` - Files map[string]*FileDef `json:"files,omitempty"` - Meta map[string]any `json:"meta,omitempty"` -} - -type WinSize struct { - Width int `json:"width"` - Height int `json:"height"` -} - -type RuntimeOpts struct { - TermSize shellexec.TermSize `json:"termsize,omitempty"` - WinSize WinSize `json:"winsize,omitempty"` -} type BlockController struct { Lock *sync.Mutex BlockId string - BlockDef *BlockDef + BlockDef *wstore.BlockDef InputCh chan BlockCommand ShellProc *shellexec.ShellProc @@ -86,9 +50,9 @@ func jsonDeepCopy(val map[string]any) (map[string]any, error) { return rtn, nil } -func CreateBlock(bdef *BlockDef, rtOpts *RuntimeOpts) (*BlockData, error) { +func CreateBlock(bdef *wstore.BlockDef, rtOpts *wstore.RuntimeOpts) (*wstore.Block, error) { blockId := uuid.New().String() - blockData := &BlockData{ + blockData := &wstore.Block{ Lock: &sync.Mutex{}, BlockId: blockId, BlockDef: bdef, @@ -101,7 +65,7 @@ func CreateBlock(bdef *BlockDef, rtOpts *RuntimeOpts) (*BlockData, error) { if err != nil { return nil, fmt.Errorf("error copying meta: %w", err) } - setBlockData(blockData) + wstore.BlockMap.Set(blockId, blockData) if blockData.Controller != "" { StartBlockController(blockId, blockData) } @@ -115,25 +79,7 @@ func CloseBlock(blockId string) { } bc.Close() close(bc.InputCh) - removeBlockData(blockId) -} - -func GetBlockData(blockId string) *BlockData { - globalLock.Lock() - defer globalLock.Unlock() - return blockDataMap[blockId] -} - -func setBlockData(bd *BlockData) { - globalLock.Lock() - defer globalLock.Unlock() - blockDataMap[bd.BlockId] = bd -} - -func removeBlockData(blockId string) { - globalLock.Lock() - defer globalLock.Unlock() - delete(blockDataMap, blockId) + wstore.BlockMap.Delete(blockId) } func (bc *BlockController) setShellProc(shellProc *shellexec.ShellProc) error { @@ -231,7 +177,7 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts) error { return nil } -func (bc *BlockController) Run(bdata *BlockData) { +func (bc *BlockController) Run(bdata *wstore.Block) { defer func() { bdata.WithLock(func() { // if the controller had an error status, don't change it @@ -272,13 +218,7 @@ func (bc *BlockController) Run(bdata *BlockData) { } } -func (b *BlockData) WithLock(f func()) { - b.Lock.Lock() - defer b.Lock.Unlock() - f() -} - -func StartBlockController(blockId string, bdata *BlockData) { +func StartBlockController(blockId string, bdata *wstore.Block) { if bdata.Controller != BlockController_Shell { log.Printf("unknown controller %q\n", bdata.Controller) bdata.WithLock(func() { @@ -312,7 +252,7 @@ func ProcessStaticCommand(blockId string, cmdGen BlockCommand) { log.Printf("MESSAGE: %s | %q\n", blockId, cmd.Message) case *SetViewCommand: log.Printf("SETVIEW: %s | %q\n", blockId, cmd.View) - block := GetBlockData(blockId) + block := wstore.BlockMap.Get(blockId) if block != nil { block.WithLock(func() { block.View = cmd.View @@ -320,7 +260,7 @@ func ProcessStaticCommand(blockId string, cmdGen BlockCommand) { } case *SetMetaCommand: log.Printf("SETMETA: %s | %v\n", blockId, cmd.Meta) - block := GetBlockData(blockId) + block := wstore.BlockMap.Get(blockId) if block != nil { block.WithLock(func() { for k, v := range cmd.Meta { diff --git a/pkg/service/blockservice/blockservice.go b/pkg/service/blockservice/blockservice.go index b832a3e3..81df911f 100644 --- a/pkg/service/blockservice/blockservice.go +++ b/pkg/service/blockservice/blockservice.go @@ -9,17 +9,18 @@ import ( "github.com/wavetermdev/thenextwave/pkg/blockcontroller" "github.com/wavetermdev/thenextwave/pkg/util/utilfn" + "github.com/wavetermdev/thenextwave/pkg/wstore" ) type BlockService struct{} func (bs *BlockService) CreateBlock(bdefMap map[string]any, rtOptsMap map[string]any) (map[string]any, error) { - var bdef blockcontroller.BlockDef + var bdef wstore.BlockDef err := utilfn.JsonMapToStruct(bdefMap, &bdef) if err != nil { return nil, fmt.Errorf("error unmarshalling BlockDef: %w", err) } - var rtOpts blockcontroller.RuntimeOpts + var rtOpts wstore.RuntimeOpts err = utilfn.JsonMapToStruct(rtOptsMap, &rtOpts) if err != nil { return nil, fmt.Errorf("error unmarshalling RuntimeOpts: %w", err) @@ -40,7 +41,7 @@ func (bs *BlockService) CloseBlock(blockId string) { } func (bs *BlockService) GetBlockData(blockId string) (map[string]any, error) { - blockData := blockcontroller.GetBlockData(blockId) + blockData := wstore.BlockMap.Get(blockId) if blockData == nil { return nil, nil } diff --git a/pkg/util/ds/syncmap.go b/pkg/util/ds/syncmap.go new file mode 100644 index 00000000..02d0f80d --- /dev/null +++ b/pkg/util/ds/syncmap.go @@ -0,0 +1,43 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +package ds + +import "sync" + +type SyncMap[T any] struct { + lock *sync.Mutex + m map[string]T +} + +func NewSyncMap[T any]() *SyncMap[T] { + return &SyncMap[T]{ + lock: &sync.Mutex{}, + m: make(map[string]T), + } +} + +func (sm *SyncMap[T]) Set(key string, value T) { + sm.lock.Lock() + defer sm.lock.Unlock() + sm.m[key] = value +} + +func (sm *SyncMap[T]) Get(key string) T { + sm.lock.Lock() + defer sm.lock.Unlock() + return sm.m[key] +} + +func (sm *SyncMap[T]) GetEx(key string) (T, bool) { + sm.lock.Lock() + defer sm.lock.Unlock() + v, ok := sm.m[key] + return v, ok +} + +func (sm *SyncMap[T]) Delete(key string) { + sm.lock.Lock() + defer sm.lock.Unlock() + delete(sm.m, key) +} diff --git a/pkg/wstore/wstore.go b/pkg/wstore/wstore.go new file mode 100644 index 00000000..5f0a0ab2 --- /dev/null +++ b/pkg/wstore/wstore.go @@ -0,0 +1,68 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +package wstore + +import ( + "sync" + + "github.com/wavetermdev/thenextwave/pkg/shellexec" + "github.com/wavetermdev/thenextwave/pkg/util/ds" +) + +var WorkspaceMap = ds.NewSyncMap[*Workspace]() +var TabMap = ds.NewSyncMap[*Tab]() +var BlockMap = ds.NewSyncMap[*Block]() + +type Workspace struct { + WorkspaceId string `json:"workspaceid"` + TabIds []string `json:"tabids"` +} + +type Tab struct { + TabId string `json:"tabid"` + Name string `json:"name"` + BlockIds []string `json:"blockids"` +} + +type FileDef struct { + FileType string `json:"filetype,omitempty"` + Path string `json:"path,omitempty"` + Url string `json:"url,omitempty"` + Content string `json:"content,omitempty"` + Meta map[string]any `json:"meta,omitempty"` +} + +type BlockDef struct { + Controller string `json:"controller"` + View string `json:"view,omitempty"` + Files map[string]*FileDef `json:"files,omitempty"` + Meta map[string]any `json:"meta,omitempty"` +} + +type RuntimeOpts struct { + TermSize shellexec.TermSize `json:"termsize,omitempty"` + WinSize WinSize `json:"winsize,omitempty"` +} + +type WinSize struct { + Width int `json:"width"` + Height int `json:"height"` +} + +type Block struct { + Lock *sync.Mutex `json:"-"` + BlockId string `json:"blockid"` + BlockDef *BlockDef `json:"blockdef"` + Controller string `json:"controller"` + ControllerStatus string `json:"controllerstatus"` + View string `json:"view"` + Meta map[string]any `json:"meta,omitempty"` + RuntimeOpts *RuntimeOpts `json:"runtimeopts,omitempty"` +} + +func (b *Block) WithLock(f func()) { + b.Lock.Lock() + defer b.Lock.Unlock() + f() +}