github.com/distbuild/reclient@v0.0.0-20240401075343-3de72e395564/cmd/scandeps/sampleclient/main.go (about) 1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Sample experiment client for connecting to a scandeps service 16 package main 17 18 import ( 19 "context" 20 "flag" 21 "os" 22 "runtime" 23 "time" 24 25 "google.golang.org/grpc/codes" 26 "google.golang.org/grpc/status" 27 28 "github.com/bazelbuild/reclient/internal/pkg/ipc" 29 30 pb "github.com/bazelbuild/reclient/api/scandeps" 31 32 log "github.com/golang/glog" 33 "github.com/google/uuid" 34 35 emptypb "google.golang.org/protobuf/types/known/emptypb" 36 ) 37 38 var ( 39 serverAddr = "127.0.0.1:8001" 40 dialTimeout = 3 * time.Minute 41 ) 42 43 func main() { 44 flag.StringVar(&serverAddr, "server_address", serverAddr, "The server address in the format of host:port for network, or unix:///file for unix domain sockets.") 45 flag.Parse() 46 ctx, cancel := context.WithTimeout(context.Background(), dialTimeout) 47 defer cancel() 48 conn, err := ipc.DialContext(ctx, serverAddr) 49 if err != nil { 50 log.Fatalf("Fail to dial %s: %v", serverAddr, err) 51 } 52 defer conn.Close() 53 54 scandeps := pb.NewCPPDepsScannerClient(conn) 55 56 cmd := []string{} 57 directory, _ := os.Getwd() 58 filename := "" 59 60 switch runtime.GOOS { 61 case "darwin": 62 log.Fatalf("Scandeps service on Mac is not yet supported") 63 case "linux": 64 filename = "tests/integ/testdata/test.cpp" 65 cmd = append(cmd, 66 // Will be downloaded from GCS by run_integ_tests.sh. 67 "tests/integ/testdata/clang/bin/clang++", 68 "--sysroot", "tests/integ/testdata/sysroot", 69 "-c", 70 "-I", 71 "tests/integ/testdata/clang/include/c++/v1", 72 "-o", "test.obj", 73 filename, 74 ) 75 case "windows": 76 filename = "tests\\integ\\testdata\\test.cpp" 77 cmd = append(cmd, 78 // Will be downloaded from GCS by prepare_chromium_integ_tests.bat 79 "tests\\integ\\testdata\\chromium\\src\\third_party\\llvm-build\\Release+Asserts\\bin\\clang-cl.exe", 80 "/nologo", 81 "/showIncludes:user", 82 "/TP", 83 "-fmsc-version=1916", 84 "/Brepro", 85 "/c", 86 "/winsysroottests\\integ\\testdata\\chromium\\src\\third_party\\depot_tools\\win_toolchain\\vs_files\\20d5f2553f", 87 "/Fo", "test.obj", 88 filename, 89 ) 90 } 91 92 for { 93 processResponse, err := scandeps.ProcessInputs( 94 context.Background(), 95 &pb.CPPProcessInputsRequest{ 96 ExecId: uuid.New().String(), 97 Command: cmd, 98 Directory: directory, 99 Filename: filename, 100 }) 101 if err != nil { 102 if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable { 103 log.Warningf("Disconnected from service during ProcessInputs; retrying after 10 seconds.") 104 time.Sleep(10) 105 log.Warningf("Retrying ProcessInputs.") 106 continue 107 } 108 log.Fatalf("ProcessInputs command failed: %v", err) 109 } 110 log.Infof("Dependencies: %v", processResponse.Dependencies) 111 log.Infof("Used cache: %t", processResponse.UsedCache) 112 break 113 } 114 115 for { 116 statusResponse, err := scandeps.Status(context.Background(), &emptypb.Empty{}) 117 if err != nil { 118 log.Errorf("Status command failed: %v", err) 119 if st, ok := status.FromError(err); ok && st.Code() == codes.Unavailable { 120 log.Warningf("Disconnected from service during Status; retrying after 10 seconds.") 121 time.Sleep(10) 122 log.Warningf("Retrying Status.") 123 continue 124 } 125 log.Fatalf("Status command failed: %v", err) 126 } 127 log.Infof("Response from %s (v%s)", statusResponse.GetName(), statusResponse.GetVersion()) 128 if statusResponse.GetUptime() != nil { 129 log.Infof("> Uptime: %d seconds", statusResponse.GetUptime().GetSeconds()) 130 } 131 log.Infof("> Completed: %d", statusResponse.GetCompletedActions()) 132 log.Infof("> In Progress: %d", statusResponse.GetRunningActions()) 133 if statusResponse.GetLongestCurrentAction() != nil { 134 log.Infof("> Longest action: %d", statusResponse.GetLongestCurrentAction().GetSeconds()) 135 } 136 break 137 } 138 log.Flush() 139 }