in internal/proxy/proxy.go [676:731]
func (c *Client) Close() error {
mnts := c.mnts
var mErr MultiErr
// If FUSE is enabled, unmount it and save a reference to any existing
// socket mounts.
if c.fuseDir != "" {
if err := c.unmountFUSE(); err != nil {
mErr = append(mErr, err)
}
mnts = c.fuseMounts()
}
// Close the dialer to prevent any additional refreshes.
cErr := c.dialer.Close()
if cErr != nil {
mErr = append(mErr, cErr)
}
// Start a timer for clean shutdown (where all connections are closed).
// While the timer runs, additional connections will be accepted.
timeout := time.After(c.conf.WaitOnClose)
t := time.NewTicker(100 * time.Millisecond)
defer t.Stop()
for {
select {
case <-t.C:
if atomic.LoadUint64(&c.connCount) > 0 {
continue
}
case <-timeout:
}
break
}
// Close all open socket listeners. Time to complete shutdown.
for _, m := range mnts {
err := m.Close()
if err != nil {
mErr = append(mErr, err)
}
}
if c.fuseDir != "" {
c.waitForFUSEMounts()
}
// Verify that all connections are closed.
open := atomic.LoadUint64(&c.connCount)
if c.conf.WaitOnClose > 0 && open > 0 {
openErr := fmt.Errorf(
"%d connection(s) still open after waiting %v", open, c.conf.WaitOnClose)
mErr = append(mErr, openErr)
}
if len(mErr) > 0 {
return mErr
}
return nil
}