| 108 | } |
| 109 | |
| 110 | func (a *App) watch() error { |
| 111 | c := make(chan error) |
| 112 | |
| 113 | go func() { |
| 114 | r := bufio.NewReader(a.stdout) |
| 115 | |
| 116 | for { |
| 117 | line, err := r.ReadString('\n') |
| 118 | if line != "" { |
| 119 | a.lines.Append(line) |
| 120 | a.lastLogLine = line |
| 121 | fmt.Fprintf(os.Stdout, "%s[%d]: %s", a.Name, a.Command.Process.Pid, line) |
| 122 | } |
| 123 | |
| 124 | if err != nil { |
| 125 | c <- err |
| 126 | return |
| 127 | } |
| 128 | } |
| 129 | }() |
| 130 | |
| 131 | var err error |
| 132 | |
| 133 | reason := "detected interval shutdown" |
| 134 | |
| 135 | select { |
| 136 | case err = <-c: |
| 137 | reason = "stdout/stderr closed" |
| 138 | err = fmt.Errorf("%s:\n\t%s", ErrUnexpectedExit, a.lastLogLine) |
| 139 | case <-a.t.Dying(): |
| 140 | err = nil |
| 141 | } |
| 142 | |
| 143 | a.Kill(reason) |
| 144 | a.Command.Wait() |
| 145 | a.pool.remove(a) |
| 146 | |
| 147 | if a.Scheme == "httpu" { |
| 148 | os.Remove(a.Address()) |
| 149 | } |
| 150 | |
| 151 | a.eventAdd("shutdown") |
| 152 | |
| 153 | fmt.Printf("* App '%s' shutdown and cleaned up\n", a.Name) |
| 154 | |
| 155 | return err |
| 156 | } |
| 157 | |
| 158 | func (a *App) idleMonitor() error { |
| 159 | ticker := time.NewTicker(10 * time.Second) |