github.com/onsi/ginkgo@v1.16.6-0.20211118180735-4e1925ba4c95/internal/parallel_support/rpc_client.go (about)

     1  package parallel_support
     2  
     3  import (
     4  	"net/rpc"
     5  	"time"
     6  
     7  	"github.com/onsi/ginkgo/types"
     8  )
     9  
    10  // TODO:
    11  // - get RPC working
    12  // - performance test
    13  // - add DeferCleanup to test helper
    14  
    15  type rpcClient struct {
    16  	serverHost string
    17  	client     *rpc.Client
    18  }
    19  
    20  func newRPCClient(serverHost string) *rpcClient {
    21  	return &rpcClient{
    22  		serverHost: serverHost,
    23  	}
    24  }
    25  
    26  func (client *rpcClient) Connect() bool {
    27  	var err error
    28  	if client.client != nil {
    29  		return true
    30  	}
    31  	client.client, err = rpc.DialHTTPPath("tcp", client.serverHost, "/")
    32  	if err != nil {
    33  		client.client = nil
    34  		return false
    35  	}
    36  	return true
    37  }
    38  
    39  func (client *rpcClient) Close() error {
    40  	return client.client.Close()
    41  }
    42  
    43  func (client *rpcClient) poll(method string, data interface{}) error {
    44  	for {
    45  		err := client.client.Call(method, voidSender, data)
    46  		if err == nil {
    47  			return nil
    48  		}
    49  		switch err.Error() {
    50  		case ErrorEarly.Error():
    51  			time.Sleep(POLLING_INTERVAL)
    52  		case ErrorGone.Error():
    53  			return ErrorGone
    54  		case ErrorFailed.Error():
    55  			return ErrorFailed
    56  		default:
    57  			return err
    58  		}
    59  	}
    60  }
    61  
    62  func (client *rpcClient) PostSuiteWillBegin(report types.Report) error {
    63  	return client.client.Call("Server.SpecSuiteWillBegin", report, voidReceiver)
    64  }
    65  
    66  func (client *rpcClient) PostDidRun(report types.SpecReport) error {
    67  	return client.client.Call("Server.DidRun", report, voidReceiver)
    68  }
    69  
    70  func (client *rpcClient) PostSuiteDidEnd(report types.Report) error {
    71  	return client.client.Call("Server.SpecSuiteDidEnd", report, voidReceiver)
    72  }
    73  
    74  func (client *rpcClient) Write(p []byte) (int, error) {
    75  	var n int
    76  	err := client.client.Call("Server.EmitOutput", p, &n)
    77  	return n, err
    78  }
    79  
    80  func (client *rpcClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error {
    81  	beforeSuiteState := BeforeSuiteState{
    82  		State: state,
    83  		Data: data,
    84  	}
    85  	return client.client.Call("Server.BeforeSuiteCompleted", beforeSuiteState, voidReceiver)
    86  }
    87  
    88  func (client *rpcClient) BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) {
    89  	var beforeSuiteState BeforeSuiteState
    90  	err := client.poll("Server.BeforeSuiteState", &beforeSuiteState)
    91  	if err == ErrorGone {
    92  		return types.SpecStateInvalid, nil, types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1()
    93  	}
    94  	return beforeSuiteState.State, beforeSuiteState.Data, err
    95  }
    96  
    97  func (client *rpcClient) BlockUntilNonprimaryProcsHaveFinished() error {
    98  	return client.poll("Server.HaveNonprimaryProcsFinished", voidReceiver)
    99  }
   100  
   101  func (client *rpcClient) BlockUntilAggregatedNonprimaryProcsReport() (types.Report, error) {
   102  	var report types.Report
   103  	err := client.poll("Server.AggregatedNonprimaryProcsReport", &report)
   104  	if err == ErrorGone {
   105  		return types.Report{}, types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing()
   106  	}
   107  	return report, err
   108  }
   109  
   110  func (client *rpcClient) FetchNextCounter() (int, error) {
   111  	var counter int
   112  	err := client.client.Call("Server.Counter", voidSender, &counter)
   113  	return counter, err
   114  }
   115  
   116  func (client *rpcClient) PostAbort() error {
   117  	return client.client.Call("Server.Abort", voidSender, voidReceiver)
   118  }
   119  
   120  func (client *rpcClient) ShouldAbort() bool {
   121  	var shouldAbort bool
   122  	client.client.Call("Server.ShouldAbort", voidSender, &shouldAbort)
   123  	return shouldAbort
   124  }