new drawer goroutine for each bar; print stack if panic
Vladimir Bauer
9 years ago
| 5 | 5 | "io" |
| 6 | 6 | "log" |
| 7 | 7 | "os" |
| 8 | "runtime" | |
| 8 | 9 | "sync" |
| 9 | 10 | "time" |
| 10 | 11 | "unicode/utf8" |
| 205 | 206 | t.Stop() |
| 206 | 207 | close(p.done) |
| 207 | 208 | }() |
| 208 | const numDrawers = 3 | |
| 209 | bars := make([]*Bar, 0, 4) | |
| 209 | bars := make([]*Bar, 0, 3) | |
| 210 | 210 | var beforeRender BeforeRender |
| 211 | 211 | var wg sync.WaitGroup |
| 212 | 212 | recoverIfPanic := func() { |
| 213 | if e := recover(); e != nil { | |
| 214 | logger.Printf("unexpected panic: %+v\n", e) | |
| 213 | if p := recover(); p != nil { | |
| 214 | logger.Printf("unexpected panic: %+v\n", p) | |
| 215 | var buf [4096]byte | |
| 216 | n := runtime.Stack(buf[:], false) | |
| 217 | os.Stderr.Write(buf[:n]) | |
| 215 | 218 | } |
| 216 | 219 | wg.Done() |
| 217 | 220 | } |
| 244 | 247 | respCh <- len(bars) |
| 245 | 248 | case beforeRender = <-p.brCh: |
| 246 | 249 | case <-t.C: |
| 250 | numBars := len(bars) | |
| 251 | ||
| 252 | if numBars == 0 { | |
| 253 | break | |
| 254 | } | |
| 255 | ||
| 247 | 256 | if beforeRender != nil { |
| 248 | 257 | beforeRender(bars) |
| 249 | 258 | } |
| 250 | 259 | |
| 251 | 260 | width, _, _ := cwriter.GetTermSize() |
| 252 | 261 | ibars := iBarsGen(bars, width) |
| 253 | c := make(chan indexedBarBuffer) | |
| 254 | wg.Add(numDrawers) | |
| 255 | for i := 0; i < numDrawers; i++ { | |
| 262 | ibbCh := make(chan indexedBarBuffer) | |
| 263 | wg.Add(numBars) | |
| 264 | for i := 0; i < numBars; i++ { | |
| 256 | 265 | go func() { |
| 257 | 266 | defer recoverIfPanic() |
| 258 | drawer(ibars, c) | |
| 267 | drawer(ibars, ibbCh) | |
| 259 | 268 | }() |
| 260 | 269 | } |
| 261 | 270 | go func() { |
| 262 | 271 | wg.Wait() |
| 263 | close(c) | |
| 272 | close(ibbCh) | |
| 264 | 273 | }() |
| 265 | 274 | |
| 266 | 275 | m := make(map[int][]byte, len(bars)) |
| 267 | for r := range c { | |
| 276 | for r := range ibbCh { | |
| 268 | 277 | m[r.index] = r.buf |
| 269 | 278 | } |
| 270 | 279 | for i := 0; i < len(bars); i++ { |
| 285 | 294 | } |
| 286 | 295 | } |
| 287 | 296 | |
| 288 | func drawer(ibars <-chan indexedBar, c chan<- indexedBarBuffer) { | |
| 297 | func drawer(ibars <-chan indexedBar, ibbCh chan<- indexedBarBuffer) { | |
| 289 | 298 | for b := range ibars { |
| 290 | 299 | buf := b.bar.bytes(b.termWidth) |
| 291 | 300 | buf = append(buf, '\n') |
| 292 | c <- indexedBarBuffer{b.index, buf} | |
| 301 | ibbCh <- indexedBarBuffer{b.index, buf} | |
| 293 | 302 | } |
| 294 | 303 | } |
| 295 | 304 | |