Skip to content

Commit

Permalink
Use better ipc response/request types, send SIGTERM not SIGKILL to pr…
Browse files Browse the repository at this point in the history
…ocs and print PID for ps
  • Loading branch information
aburdulescu committed Jan 7, 2023
1 parent b2e8efa commit c808510
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 68 deletions.
36 changes: 12 additions & 24 deletions internal/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,39 +116,27 @@ func (d *Daemon) handleIpcConn(conn net.Conn) {
rsp := ipc.Response{}
switch req.Op {
case ipc.OpPs:
rsp.Data = d.ptable.Ps()
rsp.Ps = d.ptable.Ps()
case ipc.OpStop:
names, ok := req.Data.([]any)
if !ok {
rsp.Err = "not a []any"
if len(req.Names) == 0 {
d.ptable.StopAll()
} else {
if len(names) == 0 {
d.ptable.StopAll()
} else {
for _, v := range names {
name, _ := v.(string)
if err := d.ptable.Stop(name); err != nil {
rsp.Err = err.Error()
}
for _, name := range req.Names {
if err := d.ptable.Stop(name); err != nil {
rsp.Err = err.Error()
}
}
}
case ipc.OpStart:
names, ok := req.Data.([]any)
if !ok {
rsp.Err = "not a []any"
if len(req.Names) == 0 {
if err := d.ptable.StartAll(); err != nil {
rsp.Err = err.Error()
}
} else {
if len(names) == 0 {
if err := d.ptable.StartAll(); err != nil {
for _, name := range req.Names {
if err := d.ptable.Start(name); err != nil {
rsp.Err = err.Error()
}
} else {
for _, v := range names {
name, _ := v.(string)
if err := d.ptable.Start(name); err != nil {
rsp.Err = err.Error()
}
}
}
}
default:
Expand Down
33 changes: 12 additions & 21 deletions internal/ipc/ipc.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,22 @@ func (op Op) String() string {
}

type Request struct {
Op Op
Data any `json:",omitempty"`
Op Op

// for start/stop
Names []string `json:",omitempty"`
}

type Response struct {
Err string
Data any `json:",omitempty"`
Err string

// for ps
Ps []PsResult `json:",omitempty"`
}

type PsResult struct {
Name string
Pid int
Status string
}

Expand All @@ -54,25 +59,11 @@ func Ps() ([]PsResult, error) {
if rsp.Err != "" {
return nil, errors.New(rsp.Err)
}
data, ok := rsp.Data.([]any)
if !ok {
return nil, errors.New("response data is not a slice")
}
res := make([]PsResult, 0, len(data))
for _, v := range data {
vv, _ := v.(map[string]any)
name, _ := vv["Name"].(string)
status, _ := vv["Status"].(string)
res = append(res, PsResult{
Name: name,
Status: status,
})
}
return res, nil
return rsp.Ps, nil
}

func Stop(names ...string) error {
rsp, err := execRequest(Request{Op: OpStop, Data: names})
rsp, err := execRequest(Request{Op: OpStop, Names: names})
if err != nil {
return err
}
Expand All @@ -83,7 +74,7 @@ func Stop(names ...string) error {
}

func Start(names ...string) error {
rsp, err := execRequest(Request{Op: OpStart, Data: names})
rsp, err := execRequest(Request{Op: OpStart, Names: names})
if err != nil {
return err
}
Expand Down
33 changes: 16 additions & 17 deletions internal/ipc/ipc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,6 @@ func TestPs(t *testing.T) {
}
})

t.Run("RspWithWrongDataType", func(t *testing.T) {
started := make(chan struct{})
done := make(chan struct{})

go fakeDaemon(started, done, Response{Data: "dummy"})

<-started
defer func() { <-done }()

if _, err := Ps(); err == nil {
t.Fatal("expected error")
}
})

t.Run("Ok", func(t *testing.T) {
started := make(chan struct{})
done := make(chan struct{})
Expand All @@ -100,7 +86,7 @@ func TestPs(t *testing.T) {
{Name: "b", Status: "y"},
}

go fakeDaemon(started, done, Response{Data: expected})
go fakeDaemon(started, done, Response{Ps: expected})

<-started
defer func() { <-done }()
Expand All @@ -115,8 +101,8 @@ func TestPs(t *testing.T) {
return fmt.Errorf("different len: %d %d", len(result), len(expected))
}
for i := range result {
if result[i] != expected[i] {
return fmt.Errorf("different element at index %d: %s %s", i, result[i], expected[i])
if err := psResultEqual(result[i], expected[i]); err != nil {
return fmt.Errorf("different element at index %d: %w", i, err)
}
}
return nil
Expand All @@ -128,6 +114,19 @@ func TestPs(t *testing.T) {
})
}

func psResultEqual(l, r PsResult) error {
if l.Name != r.Name {
return fmt.Errorf("different name: %s %s", l.Name, r.Name)
}
if l.Status != r.Status {
return fmt.Errorf("different status: %s %s", l.Status, r.Status)
}
if l.Pid != r.Pid {
return fmt.Errorf("different pid: %d %d", l.Pid, r.Pid)
}
return nil
}

func TestStop(t *testing.T) {
started := make(chan struct{})
done := make(chan struct{})
Expand Down
13 changes: 10 additions & 3 deletions internal/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,23 @@ type Process struct {
}

func (p *Process) UpdateState() {
p.State = Failed
if p.Cmd == nil {
return
}
if p.Cmd.ProcessState == nil {
return
}
ps := p.Cmd.ProcessState
p.State = Failed
p.Cmd = nil
if ps.Success() {
p.State = Finished
return
}
ws, _ := ps.Sys().(syscall.WaitStatus)
if ws.Signaled() {
sig := ws.Signal()
if sig == syscall.SIGTERM || sig == syscall.SIGINT {
if sig == syscall.SIGTERM || sig == syscall.SIGINT || sig == syscall.SIGKILL {
p.State = Stopped
}
}
Expand All @@ -76,9 +77,10 @@ func (p *Process) Stop() {
if p.State != Running {
return
}
if err := p.Cmd.Process.Kill(); err != nil {
if err := p.Cmd.Process.Signal(syscall.SIGTERM); err != nil {
fmt.Printf("[daemon] failed to kill [%s]: %v\n", p.Name, err)
}
// TODO: this may not actually kill it => wait to see if it stopped then send SIGKILL
}

type Table struct {
Expand Down Expand Up @@ -213,9 +215,14 @@ func (t *Table) Ps() []ipc.PsResult {
defer t.mu.Unlock()
var result []ipc.PsResult
for _, p := range t.procs {
pid := -1
if p.Cmd != nil && p.Cmd.Process != nil {
pid = p.Cmd.Process.Pid
}
result = append(result, ipc.PsResult{
Name: p.Name,
Status: p.State.String(),
Pid: pid,
})
}
return result
Expand Down
6 changes: 3 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ Options:
w := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0)
defer w.Flush()

fmt.Fprintf(w, "Name\tStatus\n")
fmt.Fprintf(w, "----\t-------\n")
fmt.Fprintf(w, "Name\tPID\tStatus\n")
fmt.Fprintf(w, "----\t---\t-------\n")

for _, s := range services {
fmt.Fprintf(w, "%s\t%s\n", s.Name, s.Status)
fmt.Fprintf(w, "%s\t%d\t%s\n", s.Name, s.Pid, s.Status)
}

return nil
Expand Down

0 comments on commit c808510

Please sign in to comment.