func (hs hostErrs) Error() string { var errs []error for _, h := range hs { errs = append(errs, h) } return build.JoinErrors(errs, "\n").Error() }
// WriteNegotiationRejection will write a rejection response to w (usually a // net.Conn) and return the input error. If the write fails, the write error // is joined with the input error. func WriteNegotiationRejection(w io.Writer, err error) error { writeErr := encoding.WriteObject(w, err.Error()) if writeErr != nil { return build.JoinErrors([]error{err, writeErr}, "; ") } return err }
// Close terminates all ongoing processes involving the wallet, enabling // garbage collection. func (w *Wallet) Close() error { if err := w.tg.Stop(); err != nil { return err } var errs []error // Lock the wallet outside of mu.Lock because Lock uses its own mu.Lock. // Once the wallet is locked it cannot be unlocked except using the // unexported unlock method (w.Unlock returns an error if the wallet's // ThreadGroup is stopped). if w.Unlocked() { if err := w.Lock(); err != nil { errs = append(errs, err) } } w.mu.Lock() defer w.mu.Unlock() w.cs.Unsubscribe(w) w.tpool.Unsubscribe(w) if err := w.log.Close(); err != nil { errs = append(errs, fmt.Errorf("log.Close failed: %v", err)) } return build.JoinErrors(errs, "; ") }
// Close saves the state of the Gateway and stops its listener process. func (g *Gateway) Close() error { if err := g.threads.Stop(); err != nil { return err } var errs []error // Unregister RPCs. Not strictly necessary for clean shutdown in this specific // case, as the handlers should only contain references to the gateway itself, // but do it anyways as an example for other modules to follow. g.UnregisterRPC("ShareNodes") g.UnregisterConnectCall("ShareNodes") // save the latest gateway state g.mu.RLock() if err := g.saveSync(); err != nil { errs = append(errs, fmt.Errorf("save failed: %v", err)) } g.mu.RUnlock() // clear the port mapping (no effect if UPnP not supported) g.mu.RLock() g.clearPort(g.myAddr.Port()) g.mu.RUnlock() // Close the logger. The logger should be the last thing to shut down so that // all other objects have access to logging while closing. if err := g.log.Close(); err != nil { errs = append(errs, fmt.Errorf("log.Close failed: %v", err)) } return build.JoinErrors(errs, "; ") }
// Close safely closes the consensus set tester. Because there's not a good way // to errcheck when deferring a close, a panic is called in the event of an // error. func (cst *consensusSetTester) Close() error { errs := []error{ cst.cs.Close(), cst.gateway.Close(), cst.miner.Close(), } if err := build.JoinErrors(errs, "; "); err != nil { panic(err) } return nil }
// Close safely closes the hostTester. It panics if err != nil because there // isn't a good way to errcheck when deferring a close. func (ht *hostTester) Close() error { errs := []error{ ht.cs.Close(), ht.gateway.Close(), ht.tpool.Close(), ht.miner.Close(), } if err := build.JoinErrors(errs, "; "); err != nil { panic(err) } return nil }
// closeWt closes all of the modules in the wallet tester. func (wt *walletTester) closeWt() { errs := []error{ wt.gateway.Close(), wt.cs.Close(), wt.tpool.Close(), wt.miner.Close(), wt.wallet.Close(), } if err := build.JoinErrors(errs, "; "); err != nil { panic(err) } }
// processConfig checks the configuration values and performs cleanup on // incorrect-but-allowed values. func processConfig(config Config) (Config, error) { var err1 error config.Siad.APIaddr = processNetAddr(config.Siad.APIaddr) config.Siad.RPCaddr = processNetAddr(config.Siad.RPCaddr) config.Siad.HostAddr = processNetAddr(config.Siad.HostAddr) config.Siad.Modules, err1 = processModules(config.Siad.Modules) err2 := verifyAPISecurity(config) err := build.JoinErrors([]error{err1, err2}, ", and ") if err != nil { return Config{}, err } return config, nil }
// Close safely closes the tpoolTester, calling a panic in the event of an // error since there isn't a good way to errcheck when deferring a Close. func (tpt *tpoolTester) Close() error { errs := []error{ tpt.cs.Close(), tpt.gateway.Close(), tpt.tpool.Close(), tpt.miner.Close(), // TODO: implement modules.Wallet.Close() // tpt.wallet.Close() } if err := build.JoinErrors(errs, "; "); err != nil { panic(err) } return nil }
// Close terminates all ongoing processes involving the miner, enabling garbage // collection. func (m *Miner) Close() error { if err := m.tg.Stop(); err != nil { return err } m.mu.Lock() defer m.mu.Unlock() m.cs.Unsubscribe(m) var errs []error if err := m.saveSync(); err != nil { errs = append(errs, fmt.Errorf("save failed: %v", err)) } if err := m.log.Close(); err != nil { errs = append(errs, fmt.Errorf("log.Close failed: %v", err)) } return build.JoinErrors(errs, "; ") }
// Close safely closes the block database. func (cs *ConsensusSet) Close() error { cs.mu.Lock() defer cs.mu.Unlock() if cs.synced { cs.gateway.UnregisterRPC("SendBlocks") cs.gateway.UnregisterRPC("RelayBlock") // COMPATv0.5.1 cs.gateway.UnregisterRPC("RelayHeader") cs.gateway.UnregisterRPC("SendBlk") cs.gateway.UnregisterConnectCall("SendBlocks") } var errs []error if err := cs.db.Close(); err != nil { errs = append(errs, fmt.Errorf("db.Close failed: %v", err)) } if err := cs.log.Close(); err != nil { errs = append(errs, fmt.Errorf("log.Close failed: %v", err)) } return build.JoinErrors(errs, "; ") }
// Close closes the Server's listener, causing the HTTP server to shut down. func (srv *Server) Close() error { var errs []error // Close the listener, which will cause Server.Serve() to return. if err := srv.listener.Close(); err != nil { errs = append(errs, fmt.Errorf("listener.Close failed: %v", err)) } // Wait for Server.Serve() to exit. We wait so that it's guaranteed that the // server has completely closed after Close() returns. This is particularly // useful during testing so that we don't exit a test before Serve() finishes. srv.wg.Wait() // Safely close each module. mods := []struct { name string c io.Closer }{ {"explorer", srv.api.explorer}, {"host", srv.api.host}, {"renter", srv.api.renter}, {"miner", srv.api.miner}, {"wallet", srv.api.wallet}, {"tpool", srv.api.tpool}, {"consensus", srv.api.cs}, {"gateway", srv.api.gateway}, } for _, mod := range mods { if mod.c != nil { if err := mod.c.Close(); err != nil { errs = append(errs, fmt.Errorf("%v.Close failed: %v", mod.name, err)) } } } return build.JoinErrors(errs, "\n") }