70 lines
1.4 KiB
Go
70 lines
1.4 KiB
Go
|
|
package coredeno
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"os/exec"
|
||
|
|
"path/filepath"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Start launches the Deno sidecar process with the given entrypoint args.
|
||
|
|
func (s *Sidecar) Start(ctx context.Context, args ...string) error {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
|
||
|
|
if s.cmd != nil {
|
||
|
|
return fmt.Errorf("coredeno: already running")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Ensure socket directory exists
|
||
|
|
sockDir := filepath.Dir(s.opts.SocketPath)
|
||
|
|
if err := os.MkdirAll(sockDir, 0755); err != nil {
|
||
|
|
return fmt.Errorf("coredeno: mkdir %s: %w", sockDir, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Remove stale socket
|
||
|
|
os.Remove(s.opts.SocketPath)
|
||
|
|
|
||
|
|
s.ctx, s.cancel = context.WithCancel(ctx)
|
||
|
|
s.cmd = exec.CommandContext(s.ctx, s.opts.DenoPath, args...)
|
||
|
|
s.done = make(chan struct{})
|
||
|
|
if err := s.cmd.Start(); err != nil {
|
||
|
|
s.cmd = nil
|
||
|
|
s.cancel()
|
||
|
|
return fmt.Errorf("coredeno: start: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Monitor in background — waits for exit, then signals done
|
||
|
|
go func() {
|
||
|
|
s.cmd.Wait()
|
||
|
|
s.mu.Lock()
|
||
|
|
s.cmd = nil
|
||
|
|
s.mu.Unlock()
|
||
|
|
close(s.done)
|
||
|
|
}()
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Stop cancels the context and waits for the process to exit.
|
||
|
|
func (s *Sidecar) Stop() error {
|
||
|
|
s.mu.RLock()
|
||
|
|
if s.cmd == nil {
|
||
|
|
s.mu.RUnlock()
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
done := s.done
|
||
|
|
s.mu.RUnlock()
|
||
|
|
|
||
|
|
s.cancel()
|
||
|
|
<-done
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// IsRunning returns true if the sidecar process is alive.
|
||
|
|
func (s *Sidecar) IsRunning() bool {
|
||
|
|
s.mu.RLock()
|
||
|
|
defer s.mu.RUnlock()
|
||
|
|
return s.cmd != nil
|
||
|
|
}
|