func (n *Node) Shutdown() {
	if n.client != nil {
		n.client.Shutdown()
	}
	if err := n.Stop(); err != nil {
		log.Printf("%s: Cannot stop node: %v", n, err)
	}
	if err := n.Cleanup(); err != nil {
		log.Printf("%s: Cannot cleanup: %v", n, err)
	}
	log.Printf("%s: Shutdown", n)
}
Shutdown stops a node and cleansup
package main
import (
	"errors"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"
	rpc "github.com/btcsuite/btcd/rpcclient"
)
var ErrConnectionTimeOut = errors.New("connection timeout")
type Args interface {
	Arguments() []string
	Command() *exec.Cmd
	RPCConnConfig() rpc.ConnConfig
	Cleanup() error
	fmt.Stringer
}
type Node struct {
	Args
	handlers *rpc.NotificationHandlers
	cmd      *exec.Cmd
	client   *rpc.Client
	pidFile  string
}
func NewNodeFromArgs(args Args, handlers *rpc.NotificationHandlers, w io.Writer) (*Node, error) {
	n := Node{
		Args:     args,
		handlers: handlers,
	}
	cmd := n.Command()
	n.cmd = cmd
	if w != nil {
		n.cmd.Stdout = w
		n.cmd.Stderr = w
	}
	return &n, nil
}
func (n *Node) Start() error {
	if err := n.cmd.Start(); err != nil {
		return err
	}
	pid, err := os.Create(filepath.Join(AppDataDir,
		fmt.Sprintf("%s.pid", n.Args)))
	if err != nil {
		return err
	}
	n.pidFile = pid.Name()
	if _, err = fmt.Fprintf(pid, "%d\n", n.cmd.Process.Pid); err != nil {
		return err
	}
	return pid.Close()
}
func (n *Node) Connect() error {
	var client *rpc.Client
	var err error
	rpcConf := n.RPCConnConfig()
	for i := 0; i < *maxConnRetries; i++ {
		if client, err = rpc.New(&rpcConf, n.handlers); err != nil {
			time.Sleep(time.Duration(i) * 50 * time.Millisecond)
			continue
		}
		break
	}
	if client == nil {
		return ErrConnectionTimeOut
	}
	n.client = client
	return nil
}
func (n *Node) Stop() error {
	if n.cmd == nil || n.cmd.Process == nil {
		return nil
	}
	defer n.cmd.Wait()
	if runtime.GOOS == "windows" {
		return n.cmd.Process.Signal(os.Kill)
	}
	return n.cmd.Process.Signal(os.Interrupt)
}
func (n *Node) Cleanup() error {
	if n.pidFile != "" {
		if err := os.Remove(n.pidFile); err != nil {
			log.Printf("Cannot remove file %s: %v", n.pidFile, err)
		}
	}
	return n.Args.Cleanup()
}