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 }