Close triggers the proxyClient to shut down.
()
| 725 | |
| 726 | // Close triggers the proxyClient to shut down. |
| 727 | func (c *Client) Close() error { |
| 728 | mnts := c.mnts |
| 729 | var mErr MultiErr |
| 730 | |
| 731 | // If FUSE is enabled, unmount it and save a reference to any existing |
| 732 | // socket mounts. |
| 733 | if c.fuseDir != "" { |
| 734 | if err := c.unmountFUSE(); err != nil { |
| 735 | mErr = append(mErr, err) |
| 736 | } |
| 737 | mnts = c.fuseMounts() |
| 738 | } |
| 739 | |
| 740 | // Close the dialer to prevent any additional refreshes. |
| 741 | cErr := c.dialer.Close() |
| 742 | if cErr != nil { |
| 743 | mErr = append(mErr, cErr) |
| 744 | } |
| 745 | |
| 746 | // Start a timer for clean shutdown (where all connections are closed). |
| 747 | // While the timer runs, additional connections will be accepted. |
| 748 | timeout := time.After(c.conf.WaitOnClose) |
| 749 | t := time.NewTicker(100 * time.Millisecond) |
| 750 | defer t.Stop() |
| 751 | for { |
| 752 | select { |
| 753 | case <-t.C: |
| 754 | if atomic.LoadUint64(&c.connCount) > 0 { |
| 755 | continue |
| 756 | } |
| 757 | case <-timeout: |
| 758 | } |
| 759 | break |
| 760 | } |
| 761 | // Close all open socket listeners. Time to complete shutdown. |
| 762 | for _, m := range mnts { |
| 763 | err := m.Close() |
| 764 | if err != nil { |
| 765 | mErr = append(mErr, err) |
| 766 | } |
| 767 | } |
| 768 | if c.fuseDir != "" { |
| 769 | c.waitForFUSEMounts() |
| 770 | } |
| 771 | // Verify that all connections are closed. |
| 772 | open := atomic.LoadUint64(&c.connCount) |
| 773 | if c.conf.WaitOnClose > 0 && open > 0 { |
| 774 | openErr := fmt.Errorf( |
| 775 | "%d connection(s) still open after waiting %v", open, c.conf.WaitOnClose) |
| 776 | mErr = append(mErr, openErr) |
| 777 | } |
| 778 | if len(mErr) > 0 { |
| 779 | return mErr |
| 780 | } |
| 781 | return nil |
| 782 | } |
| 783 | |
| 784 | // serveSocketMount persistently listens to the socketMounts listener and proxies connections to a |