@@ -56,10 +56,6 @@ func run(args []string) error {
5656 cfg.Parser = parser.NewScalametaParser(
5757 parser.WithHttpClientTimeout(60 * time.Second),
5858 )
59-
60- if err := cfg.Parser.Start(); err != nil {
61- return fmt.Errorf("starting parser: %w", err)
62- }
6359 defer func() {
6460 cfg.Parser.Stop()
6561 }()
@@ -72,10 +68,16 @@ func run(args []string) error {
7268 }
7369
7470 if cfg.PersistentWorker {
71+ // In persistent worker mode, parser initialization is deferred
72+ // to inside the loop so startup failures are reported per-request
73+ // via WorkResponse rather than killing the worker process.
7574 if err := persistentWork(&cfg); err != nil {
7675 return fmt.Errorf("while performing persistent work: %v", err)
7776 }
7877 } else {
78+ if err := cfg.Parser.Start(); err != nil {
79+ return fmt.Errorf("starting parser: %w", err)
80+ }
7981 if err := batchWork(&cfg); err != nil {
8082 return fmt.Errorf("while performing batch work: %v", err)
8183 }
@@ -103,16 +105,33 @@ func persistentWork(cfg *Config) error {
103105
104106 batchCfg, err := parseFlags(req.Arguments)
105107 if err != nil {
106- return fmt.Errorf("parsing work request arguments: %v", err)
107- }
108+ resp.ExitCode = 1
109+ resp.Output = fmt.Sprintf("parsing work request arguments: %v", err)
110+ } else {
111+ // Ensure parser is running (lazy init + restart if crashed)
112+ if !cfg.Parser.IsRunning() {
113+ cfg.Parser.Stop()
114+ if err := cfg.Parser.Start(); err != nil {
115+ log.Printf("failed to start parser: %v", err)
116+ resp.ExitCode = 1
117+ resp.Output = fmt.Sprintf("starting parser: %v", err)
118+ if err := protobuf.WriteDelimitedTo(&resp, stdout); err != nil {
119+ return fmt.Errorf("writing work response: %v", err)
120+ }
121+ if err := stdout.Flush(); err != nil {
122+ return fmt.Errorf("flushing work response: %v", err)
123+ }
124+ continue
125+ }
126+ }
108127
109- batchCfg.Parser = cfg.Parser
110- batchCfg.Cwd = cfg.Cwd
128+ batchCfg.Parser = cfg.Parser
129+ batchCfg.Cwd = cfg.Cwd
111130
112- if err := batchWork(&batchCfg); err != nil {
113- // Don't terminate the worker on batch errors; report via WorkResponse
114- resp.ExitCode = 1
115- resp.Output = fmt.Sprintf("performing persistent batch: %v", err)
131+ if err := batchWork(&batchCfg); err != nil {
132+ resp.ExitCode = 1
133+ resp.Output = fmt.Sprintf("performing persistent batch: %v", err)
134+ }
116135 }
117136
118137 if err := protobuf.WriteDelimitedTo(&resp, stdout); err != nil {
0 commit comments