MCPcopy Index your code
hub / github.com/coder/coder / close

Method close

cli/ssh.go:1366–1423  ·  view source on GitHub ↗
(err error)

Source from the content-addressed store, hash-verified

1364}
1365
1366func (c *closerStack) close(err error) {
1367 c.Lock()
1368 if c.closed {
1369 c.Unlock()
1370 <-c.allDone
1371 return
1372 }
1373 c.closed = true
1374 c.err = err
1375 c.Unlock()
1376 defer close(c.allDone)
1377 if len(c.closers) == 0 {
1378 return
1379 }
1380
1381 // We are going to work down the stack in order. If things close quickly, we trigger the
1382 // closers serially, in order. `done` is a channel that indicates the nth closer is done
1383 // closing, and we should trigger the (n-1) closer. However, if things take too long we don't
1384 // want to wait, so we also start a ticker that works down the stack and sends on `done` as
1385 // well.
1386 next := len(c.closers) - 1
1387 // here we make the buffer 2x the number of closers because we could write once for it being
1388 // actually done and once via the countdown for each closer
1389 done := make(chan int, len(c.closers)*2)
1390 startNext := func() {
1391 go func(i int) {
1392 defer func() { done <- i }()
1393 cwn := c.closers[i]
1394 cErr := cwn.closer.Close()
1395 c.logger.Debug(context.Background(),
1396 "closed item from stack", slog.F("name", cwn.name), slog.Error(cErr))
1397 }(next)
1398 next--
1399 }
1400 done <- len(c.closers) // kick us off right away
1401
1402 // start a ticking countdown in case we hang/don't close quickly
1403 countdown := len(c.closers) - 1
1404 ctx, cancel := context.WithCancel(context.Background())
1405 defer cancel()
1406 c.clock.TickerFunc(ctx, gracefulShutdownTimeout, func() error {
1407 if countdown < 0 {
1408 return nil
1409 }
1410 done <- countdown
1411 countdown--
1412 return nil
1413 }, "closerStack")
1414
1415 for n := range done { // the nth closer is done
1416 if n == 0 {
1417 return
1418 }
1419 if n-1 == next {
1420 startNext()
1421 }
1422 }
1423}

Callers 1

closeAfterContextMethod · 0.95

Calls 4

CloseMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45
ErrorMethod · 0.45

Tested by

no test coverage detected