diff --git a/cmd/server/main-server.go b/cmd/server/main-server.go index cc07160b1..f433c6015 100644 --- a/cmd/server/main-server.go +++ b/cmd/server/main-server.go @@ -29,7 +29,6 @@ import ( "github.com/wavetermdev/waveterm/pkg/wconfig" "github.com/wavetermdev/waveterm/pkg/wcore" "github.com/wavetermdev/waveterm/pkg/web" - "github.com/wavetermdev/waveterm/pkg/wlayout" "github.com/wavetermdev/waveterm/pkg/wps" "github.com/wavetermdev/waveterm/pkg/wshrpc" "github.com/wavetermdev/waveterm/pkg/wshrpc/wshremote" @@ -276,7 +275,7 @@ func main() { log.Printf("error initializing wsh and shell-integration files: %v\n", err) } }() - window, firstRun, err := wcore.EnsureInitialData() + err = wcore.EnsureInitialData() if err != nil { log.Printf("error ensuring initial data: %v\n", err) return @@ -286,28 +285,7 @@ func main() { log.Printf("error clearing temp files: %v\n", err) return } - if firstRun { - migrateErr := wstore.TryMigrateOldHistory() - if migrateErr != nil { - log.Printf("error migrating old history: %v\n", migrateErr) - } - } - if window != nil { - ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second) - defer cancelFn() - if !firstRun { - ws, err := wcore.GetWorkspace(ctx, window.WorkspaceId) - if err != nil { - log.Printf("error getting workspace: %v\n", err) - return - } - err = wlayout.BootstrapNewWorkspaceLayout(ctx, ws) - if err != nil { - log.Panicf("error applying new window layout: %v\n", err) - return - } - } - } + createMainWshClient() installShutdownSignalHandlers() startupActivityUpdate() diff --git a/pkg/wcore/block.go b/pkg/wcore/block.go new file mode 100644 index 000000000..4741883e5 --- /dev/null +++ b/pkg/wcore/block.go @@ -0,0 +1,91 @@ +package wcore + +import ( + "context" + "fmt" + "time" + + "github.com/wavetermdev/waveterm/pkg/blockcontroller" + "github.com/wavetermdev/waveterm/pkg/panichandler" + "github.com/wavetermdev/waveterm/pkg/telemetry" + "github.com/wavetermdev/waveterm/pkg/waveobj" + "github.com/wavetermdev/waveterm/pkg/wps" + "github.com/wavetermdev/waveterm/pkg/wshrpc" + "github.com/wavetermdev/waveterm/pkg/wstore" +) + +func CreateSubBlock(ctx context.Context, blockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) { + if blockDef == nil { + return nil, fmt.Errorf("blockDef is nil") + } + if blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, "") == "" { + return nil, fmt.Errorf("no view provided for new block") + } + blockData, err := wstore.CreateSubBlock(ctx, blockId, blockDef) + if err != nil { + return nil, fmt.Errorf("error creating sub block: %w", err) + } + return blockData, nil +} + +func CreateBlock(ctx context.Context, tabId string, blockDef *waveobj.BlockDef, rtOpts *waveobj.RuntimeOpts) (*waveobj.Block, error) { + if blockDef == nil { + return nil, fmt.Errorf("blockDef is nil") + } + if blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, "") == "" { + return nil, fmt.Errorf("no view provided for new block") + } + blockData, err := wstore.CreateBlock(ctx, tabId, blockDef, rtOpts) + if err != nil { + return nil, fmt.Errorf("error creating block: %w", err) + } + go func() { + defer panichandler.PanicHandler("CreateBlock:telemetry") + blockView := blockDef.Meta.GetString(waveobj.MetaKey_View, "") + if blockView == "" { + return + } + tctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second) + defer cancelFn() + telemetry.UpdateActivity(tctx, wshrpc.ActivityUpdate{ + Renderers: map[string]int{blockView: 1}, + }) + }() + return blockData, nil +} + +func DeleteBlock(ctx context.Context, blockId string) error { + block, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId) + if err != nil { + return fmt.Errorf("error getting block: %w", err) + } + if block == nil { + return nil + } + if len(block.SubBlockIds) > 0 { + for _, subBlockId := range block.SubBlockIds { + err := DeleteBlock(ctx, subBlockId) + if err != nil { + return fmt.Errorf("error deleting subblock %s: %w", subBlockId, err) + } + } + } + err = wstore.DeleteBlock(ctx, blockId) + if err != nil { + return fmt.Errorf("error deleting block: %w", err) + } + go blockcontroller.StopBlockController(blockId) + sendBlockCloseEvent(blockId) + return nil +} + +func sendBlockCloseEvent(blockId string) { + waveEvent := wps.WaveEvent{ + Event: wps.Event_BlockClose, + Scopes: []string{ + waveobj.MakeORef(waveobj.OType_Block, blockId).String(), + }, + Data: blockId, + } + wps.Broker.Publish(waveEvent) +} diff --git a/pkg/wcore/wcore.go b/pkg/wcore/wcore.go index c41cb7c3d..35d0ce3fc 100644 --- a/pkg/wcore/wcore.go +++ b/pkg/wcore/wcore.go @@ -11,12 +11,7 @@ import ( "time" "github.com/google/uuid" - "github.com/wavetermdev/waveterm/pkg/blockcontroller" - "github.com/wavetermdev/waveterm/pkg/panichandler" - "github.com/wavetermdev/waveterm/pkg/telemetry" "github.com/wavetermdev/waveterm/pkg/waveobj" - "github.com/wavetermdev/waveterm/pkg/wps" - "github.com/wavetermdev/waveterm/pkg/wshrpc" "github.com/wavetermdev/waveterm/pkg/wstore" ) @@ -28,90 +23,54 @@ import ( const DefaultTimeout = 2 * time.Second const DefaultActivateBlockTimeout = 60 * time.Second -func DeleteBlock(ctx context.Context, blockId string) error { - block, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId) - if err != nil { - return fmt.Errorf("error getting block: %w", err) - } - if block == nil { - return nil - } - if len(block.SubBlockIds) > 0 { - for _, subBlockId := range block.SubBlockIds { - err := DeleteBlock(ctx, subBlockId) - if err != nil { - return fmt.Errorf("error deleting subblock %s: %w", subBlockId, err) - } - } - } - err = wstore.DeleteBlock(ctx, blockId) - if err != nil { - return fmt.Errorf("error deleting block: %w", err) - } - go blockcontroller.StopBlockController(blockId) - sendBlockCloseEvent(blockId) - return nil -} - -func sendBlockCloseEvent(blockId string) { - waveEvent := wps.WaveEvent{ - Event: wps.Event_BlockClose, - Scopes: []string{ - waveobj.MakeORef(waveobj.OType_Block, blockId).String(), - }, - Data: blockId, - } - wps.Broker.Publish(waveEvent) -} - -// returns (new-window, first-time, error) -func EnsureInitialData() (*waveobj.Window, bool, error) { +// Ensures that the initial data is present in the store, creates an initial window if needed +func EnsureInitialData() error { // does not need to run in a transaction since it is called on startup ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second) defer cancelFn() - firstRun := false client, err := wstore.DBGetSingleton[*waveobj.Client](ctx) if err == wstore.ErrNotFound { client, err = CreateClient(ctx) if err != nil { - return nil, false, fmt.Errorf("error creating client: %w", err) + return fmt.Errorf("error creating client: %w", err) + } + migrateErr := wstore.TryMigrateOldHistory() + if migrateErr != nil { + log.Printf("error migrating old history: %v\n", migrateErr) } - firstRun = true } if client.TempOID == "" { log.Println("client.TempOID is empty") client.TempOID = uuid.NewString() err = wstore.DBUpdate(ctx, client) if err != nil { - return nil, false, fmt.Errorf("error updating client: %w", err) + return fmt.Errorf("error updating client: %w", err) } } log.Printf("clientid: %s\n", client.OID) if len(client.WindowIds) == 1 { log.Println("client has one window") - window := CheckAndFixWindow(ctx, client.WindowIds[0]) - if window != nil { - return window, firstRun, nil - } + CheckAndFixWindow(ctx, client.WindowIds[0]) + return nil } if len(client.WindowIds) > 0 { log.Println("client has windows") - return nil, false, nil + return nil } log.Println("client has no windows, creating default workspace") defaultWs, err := CreateWorkspace(ctx, "Default workspace", "circle", "green") if err != nil { - return nil, false, fmt.Errorf("error creating default workspace: %w", err) + return fmt.Errorf("error creating default workspace: %w", err) } _, err = CreateTab(ctx, defaultWs.OID, "", true) if err != nil { - return nil, false, fmt.Errorf("error creating tab: %w", err) + return fmt.Errorf("error creating tab: %w", err) } - window, err := CreateWindow(ctx, nil, defaultWs.OID) + _, err = CreateWindow(ctx, nil, defaultWs.OID) if err != nil { - return nil, false, fmt.Errorf("error creating window: %w", err) + return fmt.Errorf("error creating window: %w", err) } - return window, firstRun, nil + return nil } func CreateClient(ctx context.Context) (*waveobj.Client, error) { @@ -126,46 +85,6 @@ func CreateClient(ctx context.Context) (*waveobj.Client, error) { return client, nil } -func CreateSubBlock(ctx context.Context, blockId string, blockDef *waveobj.BlockDef) (*waveobj.Block, error) { - if blockDef == nil { - return nil, fmt.Errorf("blockDef is nil") - } - if blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, "") == "" { - return nil, fmt.Errorf("no view provided for new block") - } - blockData, err := wstore.CreateSubBlock(ctx, blockId, blockDef) - if err != nil { - return nil, fmt.Errorf("error creating sub block: %w", err) - } - return blockData, nil -} - -func CreateBlock(ctx context.Context, tabId string, blockDef *waveobj.BlockDef, rtOpts *waveobj.RuntimeOpts) (*waveobj.Block, error) { - if blockDef == nil { - return nil, fmt.Errorf("blockDef is nil") - } - if blockDef.Meta == nil || blockDef.Meta.GetString(waveobj.MetaKey_View, "") == "" { - return nil, fmt.Errorf("no view provided for new block") - } - blockData, err := wstore.CreateBlock(ctx, tabId, blockDef, rtOpts) - if err != nil { - return nil, fmt.Errorf("error creating block: %w", err) - } - go func() { - defer panichandler.PanicHandler("CreateBlock:telemetry") - blockView := blockDef.Meta.GetString(waveobj.MetaKey_View, "") - if blockView == "" { - return - } - tctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second) - defer cancelFn() - telemetry.UpdateActivity(tctx, wshrpc.ActivityUpdate{ - Renderers: map[string]int{blockView: 1}, - }) - }() - return blockData, nil -} - func GetClientData(ctx context.Context) (*waveobj.Client, error) { clientData, err := wstore.DBGetSingleton[*waveobj.Client](ctx) if err != nil {