a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
79 lines
2.5 KiB
Go
79 lines
2.5 KiB
Go
// Package crashpool runs tree-sitter extraction inside isolated worker
|
|
// subprocesses so a grammar SIGSEGV / OOM / hang on one pathological
|
|
// file cannot abort the whole index pass.
|
|
//
|
|
// A worker that dies mid-parse is detected by the parent as a broken
|
|
// pipe; the in-flight file is quarantined and a fresh worker is spawned
|
|
// to drain the rest of the queue. A worker that merely hangs is killed
|
|
// on a per-request deadline and treated the same way. A recovered Go
|
|
// panic in an extractor comes back as an ordinary error response and
|
|
// the worker stays alive.
|
|
//
|
|
// Quarantined files are persisted (Quarantine) so a file that crashes
|
|
// the parser survives daemon restarts and is skipped until its content
|
|
// changes — at which point it gets exactly one retry.
|
|
package crashpool
|
|
|
|
import (
|
|
"encoding/gob"
|
|
|
|
"github.com/zzet/gortex/internal/graph"
|
|
)
|
|
|
|
func init() {
|
|
// Node.Meta / Edge.Meta carry these concrete types inside their
|
|
// interface values; gob needs every concrete type registered to
|
|
// encode an interface. Mirrors the snapshot codec registrations in
|
|
// internal/persistence.
|
|
gob.Register(map[string]any{})
|
|
gob.Register([]any{})
|
|
gob.Register([]string{})
|
|
gob.Register([]int{})
|
|
gob.Register([]map[string]string{})
|
|
gob.Register([]map[string]any{})
|
|
}
|
|
|
|
// extractRequest is one unit of parse work sent parent → worker.
|
|
type extractRequest struct {
|
|
Seq uint64
|
|
RelPath string
|
|
Language string
|
|
Content []byte
|
|
}
|
|
|
|
// extractResponse is the worker → parent reply for one request.
|
|
type extractResponse struct {
|
|
Seq uint64
|
|
Nodes []*graph.Node
|
|
Edges []*graph.Edge
|
|
ParseErrors int
|
|
HasParseErr bool
|
|
// Err is non-empty when the extractor returned an error or
|
|
// panicked. Panicked distinguishes a recovered Go panic (the
|
|
// worker survives) from a plain error return.
|
|
Err string
|
|
Panicked bool
|
|
}
|
|
|
|
// Result is the parent-side outcome of one Submit call.
|
|
type Result struct {
|
|
Nodes []*graph.Node
|
|
Edges []*graph.Edge
|
|
ParseErrors int
|
|
HasParseErr bool
|
|
// Crashed is true when the worker subprocess died or hung
|
|
// (SIGSEGV / OOM / kill / deadline). The file should be
|
|
// quarantined and skipped.
|
|
Crashed bool
|
|
// Panicked is true when an extractor panicked but was recovered:
|
|
// the file is bad but the worker survived.
|
|
Panicked bool
|
|
// Err carries the failure detail for Crashed / Panicked / error
|
|
// responses.
|
|
Err string
|
|
}
|
|
|
|
// Bad reports whether the file failed to parse (crash, hang, panic, or
|
|
// extractor error) and should be quarantined.
|
|
func (r Result) Bad() bool { return r.Crashed || r.Panicked || r.Err != "" }
|