mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
checkpoint on integratng wstore. moved to wails data structures, got immer working again, Window object, transitioned to generic DB ops, lots more
This commit is contained in:
@@ -4,12 +4,14 @@
|
||||
package blockcontroller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/creack/pty"
|
||||
"github.com/google/uuid"
|
||||
@@ -24,6 +26,8 @@ const (
|
||||
BlockController_Cmd = "cmd"
|
||||
)
|
||||
|
||||
const DefaultTimeout = 2 * time.Second
|
||||
|
||||
var globalLock = &sync.Mutex{}
|
||||
var blockControllerMap = make(map[string]*BlockController)
|
||||
|
||||
@@ -32,11 +36,18 @@ type BlockController struct {
|
||||
BlockId string
|
||||
BlockDef *wstore.BlockDef
|
||||
InputCh chan BlockCommand
|
||||
Status string
|
||||
|
||||
ShellProc *shellexec.ShellProc
|
||||
ShellInputCh chan *InputCommand
|
||||
}
|
||||
|
||||
func (bc *BlockController) WithLock(f func()) {
|
||||
bc.Lock.Lock()
|
||||
defer bc.Lock.Unlock()
|
||||
f()
|
||||
}
|
||||
|
||||
func jsonDeepCopy(val map[string]any) (map[string]any, error) {
|
||||
barr, err := json.Marshal(val)
|
||||
if err != nil {
|
||||
@@ -50,10 +61,9 @@ func jsonDeepCopy(val map[string]any) (map[string]any, error) {
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
func CreateBlock(bdef *wstore.BlockDef, rtOpts *wstore.RuntimeOpts) (*wstore.Block, error) {
|
||||
func CreateBlock(ctx context.Context, bdef *wstore.BlockDef, rtOpts *wstore.RuntimeOpts) (*wstore.Block, error) {
|
||||
blockId := uuid.New().String()
|
||||
blockData := &wstore.Block{
|
||||
Lock: &sync.Mutex{},
|
||||
BlockId: blockId,
|
||||
BlockDef: bdef,
|
||||
Controller: bdef.Controller,
|
||||
@@ -65,7 +75,10 @@ func CreateBlock(bdef *wstore.BlockDef, rtOpts *wstore.RuntimeOpts) (*wstore.Blo
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error copying meta: %w", err)
|
||||
}
|
||||
wstore.BlockMap.Set(blockId, blockData)
|
||||
err = wstore.DBInsert(ctx, blockData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error inserting block: %w", err)
|
||||
}
|
||||
if blockData.Controller != "" {
|
||||
StartBlockController(blockId, blockData)
|
||||
}
|
||||
@@ -179,10 +192,10 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts) error {
|
||||
|
||||
func (bc *BlockController) Run(bdata *wstore.Block) {
|
||||
defer func() {
|
||||
bdata.WithLock(func() {
|
||||
bc.WithLock(func() {
|
||||
// if the controller had an error status, don't change it
|
||||
if bdata.ControllerStatus == "running" {
|
||||
bdata.ControllerStatus = "done"
|
||||
if bc.Status == "running" {
|
||||
bc.Status = "done"
|
||||
}
|
||||
})
|
||||
eventbus.SendEvent(application.WailsEvent{
|
||||
@@ -193,8 +206,8 @@ func (bc *BlockController) Run(bdata *wstore.Block) {
|
||||
defer globalLock.Unlock()
|
||||
delete(blockControllerMap, bc.BlockId)
|
||||
}()
|
||||
bdata.WithLock(func() {
|
||||
bdata.ControllerStatus = "running"
|
||||
bc.WithLock(func() {
|
||||
bc.Status = "running"
|
||||
})
|
||||
|
||||
// only controller is "shell" for now
|
||||
@@ -221,9 +234,6 @@ func (bc *BlockController) Run(bdata *wstore.Block) {
|
||||
func StartBlockController(blockId string, bdata *wstore.Block) {
|
||||
if bdata.Controller != BlockController_Shell {
|
||||
log.Printf("unknown controller %q\n", bdata.Controller)
|
||||
bdata.WithLock(func() {
|
||||
bdata.ControllerStatus = "error"
|
||||
})
|
||||
return
|
||||
}
|
||||
globalLock.Lock()
|
||||
@@ -234,6 +244,7 @@ func StartBlockController(blockId string, bdata *wstore.Block) {
|
||||
bc := &BlockController{
|
||||
Lock: &sync.Mutex{},
|
||||
BlockId: blockId,
|
||||
Status: "init",
|
||||
InputCh: make(chan BlockCommand),
|
||||
}
|
||||
blockControllerMap[blockId] = bc
|
||||
@@ -246,31 +257,47 @@ func GetBlockController(blockId string) *BlockController {
|
||||
return blockControllerMap[blockId]
|
||||
}
|
||||
|
||||
func ProcessStaticCommand(blockId string, cmdGen BlockCommand) {
|
||||
func ProcessStaticCommand(blockId string, cmdGen BlockCommand) error {
|
||||
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
|
||||
defer cancelFn()
|
||||
switch cmd := cmdGen.(type) {
|
||||
case *MessageCommand:
|
||||
log.Printf("MESSAGE: %s | %q\n", blockId, cmd.Message)
|
||||
return nil
|
||||
case *SetViewCommand:
|
||||
log.Printf("SETVIEW: %s | %q\n", blockId, cmd.View)
|
||||
block := wstore.BlockMap.Get(blockId)
|
||||
if block != nil {
|
||||
block.WithLock(func() {
|
||||
block.View = cmd.View
|
||||
})
|
||||
block, err := wstore.DBGet[wstore.Block](ctx, blockId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting block: %w", err)
|
||||
}
|
||||
block.View = cmd.View
|
||||
err = wstore.DBUpdate[wstore.Block](ctx, block)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating block: %w", err)
|
||||
}
|
||||
return nil
|
||||
case *SetMetaCommand:
|
||||
log.Printf("SETMETA: %s | %v\n", blockId, cmd.Meta)
|
||||
block := wstore.BlockMap.Get(blockId)
|
||||
if block != nil {
|
||||
block.WithLock(func() {
|
||||
for k, v := range cmd.Meta {
|
||||
if v == nil {
|
||||
delete(block.Meta, k)
|
||||
continue
|
||||
}
|
||||
block.Meta[k] = v
|
||||
}
|
||||
})
|
||||
block, err := wstore.DBGet[wstore.Block](ctx, blockId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting block: %w", err)
|
||||
}
|
||||
if block == nil {
|
||||
return nil
|
||||
}
|
||||
for k, v := range cmd.Meta {
|
||||
if v == nil {
|
||||
delete(block.Meta, k)
|
||||
continue
|
||||
}
|
||||
block.Meta[k] = v
|
||||
}
|
||||
err = wstore.DBUpdate(ctx, block)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating block: %w", err)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unknown command type %T", cmdGen)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user