From 6e9439f4e3344dbdea9aa4e215700774bb217ed1 Mon Sep 17 00:00:00 2001 From: James Shubin Date: Thu, 14 Jan 2016 23:58:49 -0500 Subject: [PATCH] Avoid panic's when referencing non-existing objects No idea why wrapping the cmd in a function avoids a panic. Probably something about the gc... --- examples/graph8d.yaml | 15 +++++++++++++++ exec.go | 8 ++++++-- types.go | 12 ++++++++---- 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 examples/graph8d.yaml diff --git a/examples/graph8d.yaml b/examples/graph8d.yaml new file mode 100644 index 00000000..4433ea59 --- /dev/null +++ b/examples/graph8d.yaml @@ -0,0 +1,15 @@ +--- +graph: mygraph +types: + exec: + - name: exec1 + cmd: echo hello from exec1 + shell: '' + timeout: 0 + watchcmd: sleep 5s + watchshell: '' + ifcmd: '' + ifshell: '' + pollint: 0 + state: present +edges: [] diff --git a/exec.go b/exec.go index bc5eab89..d84683e6 100644 --- a/exec.go +++ b/exec.go @@ -132,8 +132,12 @@ func (obj *ExecType) Watch() { } scanner := bufio.NewScanner(cmdReader) - defer cmd.Wait() // XXX: is this necessary? - defer cmd.Process.Kill() // TODO: is this necessary? + defer cmd.Wait() // XXX: is this necessary? + defer func() { + // FIXME: without wrapping this in this func it panic's + // when running examples/graph8d.yaml + cmd.Process.Kill() // TODO: is this necessary? + }() if err := cmd.Start(); err != nil { log.Printf("%v[%v]: Error starting Cmd: %v", obj.GetType(), obj.GetName(), err) log.Fatal(err) // XXX: how should we handle errors? diff --git a/types.go b/types.go index 25174f09..0aeaf9dd 100644 --- a/types.go +++ b/types.go @@ -52,7 +52,7 @@ type Type interface { SetVertex(*Vertex) SetConvegedCallback(ctimeout int, converged chan bool) Compare(Type) bool - SendEvent(eventName, bool, bool) + SendEvent(eventName, bool, bool) bool IsWatching() bool SetWatching(bool) GetConvergedState() typeConvergedState @@ -234,10 +234,14 @@ func (obj *BaseType) BackPoke() { } // push an event into the message queue for a particular type vertex -func (obj *BaseType) SendEvent(event eventName, sync bool, activity bool) { +func (obj *BaseType) SendEvent(event eventName, sync bool, activity bool) bool { + // TODO: isn't this race-y ? + if !obj.IsWatching() { // element has already exited + return false // if we don't return, we'll block on the send + } if !sync { obj.events <- Event{event, nil, "", activity} - return + return true } resp := make(chan bool) @@ -246,7 +250,7 @@ func (obj *BaseType) SendEvent(event eventName, sync bool, activity bool) { value := <-resp // wait until true value if value { - return + return true } } }