[chore](dev): keep one Delve server across hot reloads
Replace Air's kill-and-rerun loop in the debug image with the pilot persistent-delve supervisor: src/dev/dlv-watch.sh owns one headless `dlv exec --multiclient --continue` server, rebuilds ./tmp/main on save and restarts only the debug target through the tiny rpc2 client in src/dev/dlv-restart. An attached VS Code session (and its breakpoints) now survives saves instead of reconnecting after every reload. The debug compose builds locally with `pull_policy: build` and without `build.network: host`: compose cannot grant the network.host entitlement, so a cold `up` previously failed with "additional privileges requested"; the default bridge reaches the dev Gitea for module resolution.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2026 Dcntrlized
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// dlv-restart is a minimal JSON-RPC client (delve service/rpc2) that restarts
|
||||
// the debug target of a persistent headless dlv server and resumes it.
|
||||
//
|
||||
// Why not `printf 'restart\n' | dlv connect ...`? `dlv connect` is an
|
||||
// interactive terminal client: its stdout/stderr is distinct from the debug
|
||||
// target's, it always reads go-ahead from the same stream, and its stdin EOF
|
||||
// makes it drop into the (dlv) prompt and exit with a "kill the headless
|
||||
// instance?" prompt — dumping the debugee's full state and racing the attached
|
||||
// vscode-go client. This helper speaks rpc2 directly, so it only issues the
|
||||
// RPCs we want, prints nothing, and exits without disturbing the target or the
|
||||
// VS Code session.
|
||||
//
|
||||
// Usage: dlv-restart [addr] (addr defaults to 127.0.0.1:2345)
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/go-delve/delve/service/rpc2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
addr := "127.0.0.1:2345"
|
||||
if len(os.Args) > 1 {
|
||||
addr = os.Args[1]
|
||||
}
|
||||
|
||||
client := rpc2.NewClient(addr)
|
||||
|
||||
discarded, err := client.RestartFrom(false, "", false, nil, [3]string{}, false)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "dlv-restart: Restart failed: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, d := range discarded {
|
||||
fmt.Fprintf(os.Stderr, "discarded %s: %v\n", d.Breakpoint.Name, d.Reason)
|
||||
}
|
||||
|
||||
// The restarted process begins halted, so resume it with Continue, then
|
||||
// close the connection. --accept-multiclient keeps the server and target
|
||||
// running while our short-lived client disconnects; an attached vscode-go
|
||||
// client is undisturbed.
|
||||
if err := client.Disconnect(true); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "dlv-restart: disconnect failed: %v\n", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user