github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/plugin/v7/rpc/cli_rpc_server.go (about)

     1  // +build V7
     2  
     3  package rpc
     4  
     5  import (
     6  	"code.cloudfoundry.org/cli/command"
     7  	plugin "code.cloudfoundry.org/cli/plugin/v7"
     8  
     9  	"fmt"
    10  	"net"
    11  	"net/rpc"
    12  	"strconv"
    13  
    14  	"bytes"
    15  	"io"
    16  
    17  	"sync"
    18  )
    19  
    20  type CliRpcService struct {
    21  	listener net.Listener
    22  	stopCh   chan struct{}
    23  	Pinged   bool
    24  	RpcCmd   *CliRpcCmd
    25  	Server   *rpc.Server
    26  }
    27  type OutputCapture interface {
    28  	SetOutputBucket(io.Writer)
    29  }
    30  
    31  //go:generate counterfeiter . TerminalOutputSwitch
    32  
    33  type TerminalOutputSwitch interface {
    34  	DisableTerminalOutput(bool)
    35  }
    36  
    37  func NewRpcService(
    38  	outputCapture OutputCapture,
    39  	terminalOutputSwitch TerminalOutputSwitch,
    40  	w io.Writer,
    41  	rpcServer *rpc.Server,
    42  	config command.Config,
    43  	pluginActor PluginActor,
    44  ) (*CliRpcService, error) {
    45  	rpcService := &CliRpcService{
    46  		Server: rpcServer,
    47  		RpcCmd: &CliRpcCmd{
    48  			PluginMetadata:       &plugin.PluginMetadata{},
    49  			MetadataMutex:        &sync.RWMutex{},
    50  			Config:               config,
    51  			PluginActor:          pluginActor,
    52  			outputCapture:        outputCapture,
    53  			terminalOutputSwitch: terminalOutputSwitch,
    54  			outputBucket:         &bytes.Buffer{},
    55  			stdout:               w,
    56  		},
    57  	}
    58  
    59  	err := rpcService.Server.Register(rpcService.RpcCmd)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	return rpcService, nil
    65  }
    66  
    67  func (cli *CliRpcService) Stop() {
    68  	close(cli.stopCh)
    69  	cli.listener.Close()
    70  }
    71  
    72  func (cli *CliRpcService) Port() string {
    73  	return strconv.Itoa(cli.listener.Addr().(*net.TCPAddr).Port)
    74  }
    75  
    76  func (cli *CliRpcService) Start() error {
    77  	var err error
    78  
    79  	cli.stopCh = make(chan struct{})
    80  
    81  	cli.listener, err = net.Listen("tcp", "127.0.0.1:0")
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	go func() {
    87  		for {
    88  			conn, err := cli.listener.Accept()
    89  			if err != nil {
    90  				select {
    91  				case <-cli.stopCh:
    92  					return
    93  				default:
    94  					fmt.Println(err)
    95  				}
    96  			} else {
    97  				go cli.Server.ServeConn(conn)
    98  			}
    99  		}
   100  	}()
   101  
   102  	return nil
   103  }