-
Notifications
You must be signed in to change notification settings - Fork 41
Description
Getting:
2015/10/30 23:10:40 http: panic serving [::1]:56269: tomb.Go called after all goroutines terminated
The use case may be not quite what you had envisioned.
I'm waiting on a usb/serial device and want to be able to cancel waiting (ctrl-c to kill the process hangs indefinitely right now because I can't close the port while I'm still waiting on an outstanding read that will never arrive).
so the flow is:
DoSomeProcessing()
...
func (msngr *Messenger) ReceiveAsync() (Message, error) {
ch := make(chan recieveAsync)
msngr.logger.Info.Println("Entering Tomb")
msngr.tomb.Go(
func() error {
message, err := msngr.receive()
messageRecieved := recieveAsync{Msg: message, Err: err}
select {
case ch <- messageRecieved:
close(ch)
case <-msngr.tomb.Dying():
msngr.logger.Info.Println("Got dying from tomb")
rec := recieveAsync{Msg: Message{}, Err: errors.New("Received Cancellation")}
ch <- rec
close(ch)
}
return nil
})
rec := <-ch
msngr.logger.Info.Println("exiting tomb")
return rec.Msg, rec.Err
}
So during execution the process should enter that, block on the rec:=<- ch multiple times, but also provide me the ability to kill it externall (on ctrl-c in this case).
At least that's the theory and it works the first time, my logs seem to indicate that the failure occurs after multiple reads, I don't see an overlap and an overlap shouldn't happen in normal process flow.
I'm pretty sure i'm missing something fundamental here, just not sure what it is. I'm also not returning a useful error at this point, I'm not sure how to approach that just yet.