func main() { var ( transport = flag.String("transport", "httpjson", "httpjson, grpc, netrpc, thrift") httpAddr = flag.String("http.addr", "localhost:8001", "Address for HTTP (JSON) server") grpcAddr = flag.String("grpc.addr", "localhost:8002", "Address for gRPC server") netrpcAddr = flag.String("netrpc.addr", "localhost:8003", "Address for net/rpc server") thriftAddr = flag.String("thrift.addr", "localhost:8004", "Address for Thrift server") thriftProtocol = flag.String("thrift.protocol", "binary", "binary, compact, json, simplejson") thriftBufferSize = flag.Int("thrift.buffer.size", 0, "0 for unbuffered") thriftFramed = flag.Bool("thrift.framed", false, "true to enable framing") ) flag.Parse() if len(os.Args) < 4 { fmt.Fprintf(os.Stderr, "\n%s [flags] method arg1 arg2\n\n", filepath.Base(os.Args[0])) flag.Usage() os.Exit(1) } root := context.Background() method, s1, s2 := flag.Arg(0), flag.Arg(1), flag.Arg(2) var logger log.Logger logger = log.NewLogfmtLogger(os.Stdout) logger = log.NewContext(logger).With("caller", log.DefaultCaller) logger = log.NewContext(logger).With("transport", *transport) var svc server.AddService switch *transport { case "grpc": cc, err := grpc.Dial(*grpcAddr) if err != nil { _ = logger.Log("err", err) os.Exit(1) } defer cc.Close() svc = grpcclient.New(root, cc, logger) case "httpjson": rawurl := *httpAddr if !strings.HasPrefix("http", rawurl) { rawurl = "http://" + rawurl } baseurl, err := url.Parse(rawurl) if err != nil { _ = logger.Log("err", err) os.Exit(1) } svc = httpjsonclient.New(root, baseurl, logger, nil) case "netrpc": cli, err := rpc.DialHTTP("tcp", *netrpcAddr) if err != nil { _ = logger.Log("err", err) os.Exit(1) } defer cli.Close() svc = netrpcclient.New(cli, logger) case "thrift": var protocolFactory thrift.TProtocolFactory switch *thriftProtocol { case "compact": protocolFactory = thrift.NewTCompactProtocolFactory() case "simplejson": protocolFactory = thrift.NewTSimpleJSONProtocolFactory() case "json": protocolFactory = thrift.NewTJSONProtocolFactory() case "binary", "": protocolFactory = thrift.NewTBinaryProtocolFactoryDefault() default: _ = logger.Log("protocol", *thriftProtocol, "err", "invalid protocol") os.Exit(1) } var transportFactory thrift.TTransportFactory if *thriftBufferSize > 0 { transportFactory = thrift.NewTBufferedTransportFactory(*thriftBufferSize) } else { transportFactory = thrift.NewTTransportFactory() } if *thriftFramed { transportFactory = thrift.NewTFramedTransportFactory(transportFactory) } transportSocket, err := thrift.NewTSocket(*thriftAddr) if err != nil { _ = logger.Log("during", "thrift.NewTSocket", "err", err) os.Exit(1) } trans := transportFactory.GetTransport(transportSocket) defer trans.Close() if err := trans.Open(); err != nil { _ = logger.Log("during", "thrift transport.Open", "err", err) os.Exit(1) } cli := thriftadd.NewAddServiceClientFactory(trans, protocolFactory) svc = thriftclient.New(cli, logger) default: _ = logger.Log("err", "invalid transport") os.Exit(1) } begin := time.Now() switch method { case "sum": a, _ := strconv.Atoi(s1) b, _ := strconv.Atoi(s2) v := svc.Sum(a, b) _ = logger.Log("method", "sum", "a", a, "b", b, "v", v, "took", time.Since(begin)) case "concat": a, b := s1, s2 v := svc.Concat(a, b) _ = logger.Log("method", "concat", "a", a, "b", b, "v", v, "took", time.Since(begin)) default: _ = logger.Log("err", "invalid method "+method) os.Exit(1) } }
func main() { var ( transport = flag.String("transport", "httpjson", "httpjson, grpc, netrpc, thrift") httpAddrs = flag.String("http.addrs", "localhost:8001", "Comma-separated list of addresses for HTTP (JSON) servers") grpcAddrs = flag.String("grpc.addrs", "localhost:8002", "Comma-separated list of addresses for gRPC servers") netrpcAddrs = flag.String("netrpc.addrs", "localhost:8003", "Comma-separated list of addresses for net/rpc servers") thriftAddrs = flag.String("thrift.addrs", "localhost:8004", "Comma-separated list of addresses for Thrift servers") thriftProtocol = flag.String("thrift.protocol", "binary", "binary, compact, json, simplejson") thriftBufferSize = flag.Int("thrift.buffer.size", 0, "0 for unbuffered") thriftFramed = flag.Bool("thrift.framed", false, "true to enable framing") // Two OpenTracing backends (to demonstrate how they can be interchanged): appdashAddr = flag.String("appdash.addr", "", "Enable Appdash tracing via an Appdash server host:port") lightstepAccessToken = flag.String("lightstep.token", "", "Enable LightStep tracing via a LightStep access token") ) flag.Parse() if len(os.Args) < 4 { fmt.Fprintf(os.Stderr, "\n%s [flags] method arg1 arg2\n\n", filepath.Base(os.Args[0])) flag.Usage() os.Exit(1) } randomSeed := time.Now().UnixNano() root := context.Background() method, s1, s2 := flag.Arg(0), flag.Arg(1), flag.Arg(2) var logger log.Logger logger = log.NewLogfmtLogger(os.Stdout) logger = log.NewContext(logger).With("caller", log.DefaultCaller) logger = log.NewContext(logger).With("transport", *transport) tracingLogger := log.NewContext(logger).With("component", "tracing") // Set up OpenTracing var tracer opentracing.Tracer { switch { case *appdashAddr != "" && *lightstepAccessToken == "": tracer = appdashot.NewTracer(appdash.NewRemoteCollector(*appdashAddr)) case *appdashAddr == "" && *lightstepAccessToken != "": tracer = lightstep.NewTracer(lightstep.Options{ AccessToken: *lightstepAccessToken, }) defer lightstep.FlushLightStepTracer(tracer) case *appdashAddr == "" && *lightstepAccessToken == "": tracer = opentracing.GlobalTracer() // no-op default: panic("specify either -appdash.addr or -lightstep.access.token, not both") } } var ( instances []string sumFactory, concatFactory loadbalancer.Factory ) switch *transport { case "grpc": instances = strings.Split(*grpcAddrs, ",") sumFactory = grpcclient.MakeSumEndpointFactory(tracer, tracingLogger) concatFactory = grpcclient.MakeConcatEndpointFactory(tracer, tracingLogger) case "httpjson": instances = strings.Split(*httpAddrs, ",") for i, rawurl := range instances { if !strings.HasPrefix("http", rawurl) { instances[i] = "http://" + rawurl } } sumFactory = httpjsonclient.MakeSumEndpointFactory(tracer, tracingLogger) concatFactory = httpjsonclient.MakeConcatEndpointFactory(tracer, tracingLogger) case "netrpc": instances = strings.Split(*netrpcAddrs, ",") sumFactory = netrpcclient.SumEndpointFactory concatFactory = netrpcclient.ConcatEndpointFactory case "thrift": instances = strings.Split(*thriftAddrs, ",") thriftClient := thriftclient.New(*thriftProtocol, *thriftBufferSize, *thriftFramed, logger) sumFactory = thriftClient.SumEndpoint concatFactory = thriftClient.ConcatEndpoint default: logger.Log("err", "invalid transport") os.Exit(1) } sum := buildEndpoint(tracer, "sum", instances, sumFactory, randomSeed, logger) concat := buildEndpoint(tracer, "concat", instances, concatFactory, randomSeed, logger) svc := newClient(root, sum, concat, logger) begin := time.Now() switch method { case "sum": a, _ := strconv.Atoi(s1) b, _ := strconv.Atoi(s2) v := svc.Sum(a, b) logger.Log("method", "sum", "a", a, "b", b, "v", v, "took", time.Since(begin)) case "concat": a, b := s1, s2 v := svc.Concat(a, b) logger.Log("method", "concat", "a", a, "b", b, "v", v, "took", time.Since(begin)) default: logger.Log("err", "invalid method "+method) os.Exit(1) } }
func main() { var ( transport = flag.String("transport", "httpjson", "httpjson, grpc, netrpc, thrift") httpAddrs = flag.String("http.addrs", "localhost:8001", "Comma-separated list of addresses for HTTP (JSON) servers") grpcAddrs = flag.String("grpc.addrs", "localhost:8002", "Comma-separated list of addresses for gRPC servers") netrpcAddrs = flag.String("netrpc.addrs", "localhost:8003", "Comma-separated list of addresses for net/rpc servers") thriftAddrs = flag.String("thrift.addrs", "localhost:8004", "Comma-separated list of addresses for Thrift servers") thriftProtocol = flag.String("thrift.protocol", "binary", "binary, compact, json, simplejson") thriftBufferSize = flag.Int("thrift.buffer.size", 0, "0 for unbuffered") thriftFramed = flag.Bool("thrift.framed", false, "true to enable framing") ) flag.Parse() if len(os.Args) < 4 { fmt.Fprintf(os.Stderr, "\n%s [flags] method arg1 arg2\n\n", filepath.Base(os.Args[0])) flag.Usage() os.Exit(1) } randomSeed := time.Now().UnixNano() root := context.Background() method, s1, s2 := flag.Arg(0), flag.Arg(1), flag.Arg(2) var logger log.Logger logger = log.NewLogfmtLogger(os.Stdout) logger = log.NewContext(logger).With("caller", log.DefaultCaller) logger = log.NewContext(logger).With("transport", *transport) var ( instances []string sumFactory, concatFactory loadbalancer.Factory ) switch *transport { case "grpc": instances = strings.Split(*grpcAddrs, ",") sumFactory = grpcclient.SumEndpointFactory concatFactory = grpcclient.ConcatEndpointFactory case "httpjson": instances = strings.Split(*httpAddrs, ",") for i, rawurl := range instances { if !strings.HasPrefix("http", rawurl) { instances[i] = "http://" + rawurl } } sumFactory = httpjsonclient.SumEndpointFactory concatFactory = httpjsonclient.ConcatEndpointFactory case "netrpc": instances = strings.Split(*netrpcAddrs, ",") sumFactory = netrpcclient.SumEndpointFactory concatFactory = netrpcclient.ConcatEndpointFactory case "thrift": instances = strings.Split(*thriftAddrs, ",") thriftClient := thriftclient.New(*thriftProtocol, *thriftBufferSize, *thriftFramed, logger) sumFactory = thriftClient.SumEndpoint concatFactory = thriftClient.ConcatEndpoint default: logger.Log("err", "invalid transport") os.Exit(1) } sum := buildEndpoint(instances, sumFactory, randomSeed, logger) concat := buildEndpoint(instances, concatFactory, randomSeed, logger) svc := newClient(root, sum, concat, logger) begin := time.Now() switch method { case "sum": a, _ := strconv.Atoi(s1) b, _ := strconv.Atoi(s2) v := svc.Sum(a, b) logger.Log("method", "sum", "a", a, "b", b, "v", v, "took", time.Since(begin)) case "concat": a, b := s1, s2 v := svc.Concat(a, b) logger.Log("method", "concat", "a", a, "b", b, "v", v, "took", time.Since(begin)) default: logger.Log("err", "invalid method "+method) os.Exit(1) } }
func main() { // The addcli presumes no service discovery system, and expects users to // provide the direct address of an addsvc. This presumption is reflected in // the addcli binary and the the client packages: the -transport.addr flags // and various client constructors both expect host:port strings. For an // example service with a client built on top of a service discovery system, // see profilesvc. var ( httpAddr = flag.String("http.addr", "", "HTTP address of addsvc") grpcAddr = flag.String("grpc.addr", "", "gRPC (HTTP) address of addsvc") thriftAddr = flag.String("thrift.addr", "", "Thrift address of addsvc") thriftProtocol = flag.String("thrift.protocol", "binary", "binary, compact, json, simplejson") thriftBufferSize = flag.Int("thrift.buffer.size", 0, "0 for unbuffered") thriftFramed = flag.Bool("thrift.framed", false, "true to enable framing") zipkinAddr = flag.String("zipkin.addr", "", "Enable Zipkin tracing via a Kafka Collector host:port") appdashAddr = flag.String("appdash.addr", "", "Enable Appdash tracing via an Appdash server host:port") lightstepToken = flag.String("lightstep.token", "", "Enable LightStep tracing via a LightStep access token") method = flag.String("method", "sum", "sum, concat") ) flag.Parse() if len(flag.Args()) != 2 { fmt.Fprintf(os.Stderr, "usage: addcli [flags] <a> <b>\n") os.Exit(1) } // This is a demonstration client, which supports multiple tracers. // Your clients will probably just use one tracer. var tracer stdopentracing.Tracer { if *zipkinAddr != "" { collector, err := zipkin.NewKafkaCollector( strings.Split(*zipkinAddr, ","), zipkin.KafkaLogger(log.NewNopLogger()), ) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } tracer, err = zipkin.NewTracer( zipkin.NewRecorder(collector, false, "localhost:8000", "addcli"), ) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } } else if *appdashAddr != "" { tracer = appdashot.NewTracer(appdash.NewRemoteCollector(*appdashAddr)) } else if *lightstepToken != "" { tracer = lightstep.NewTracer(lightstep.Options{ AccessToken: *lightstepToken, }) defer lightstep.FlushLightStepTracer(tracer) } else { tracer = stdopentracing.GlobalTracer() // no-op } } // This is a demonstration client, which supports multiple transports. // Your clients will probably just define and stick with 1 transport. var ( service addsvc.Service err error ) if *httpAddr != "" { service, err = httpclient.New(*httpAddr, tracer, log.NewNopLogger()) } else if *grpcAddr != "" { conn, err := grpc.Dial(*grpcAddr, grpc.WithInsecure(), grpc.WithTimeout(time.Second)) if err != nil { fmt.Fprintf(os.Stderr, "error: %v", err) os.Exit(1) } defer conn.Close() service = grpcclient.New(conn, tracer, log.NewNopLogger()) } else if *thriftAddr != "" { // It's necessary to do all of this construction in the func main, // because (among other reasons) we need to control the lifecycle of the // Thrift transport, i.e. close it eventually. var protocolFactory thrift.TProtocolFactory switch *thriftProtocol { case "compact": protocolFactory = thrift.NewTCompactProtocolFactory() case "simplejson": protocolFactory = thrift.NewTSimpleJSONProtocolFactory() case "json": protocolFactory = thrift.NewTJSONProtocolFactory() case "binary", "": protocolFactory = thrift.NewTBinaryProtocolFactoryDefault() default: fmt.Fprintf(os.Stderr, "error: invalid protocol %q\n", *thriftProtocol) os.Exit(1) } var transportFactory thrift.TTransportFactory if *thriftBufferSize > 0 { transportFactory = thrift.NewTBufferedTransportFactory(*thriftBufferSize) } else { transportFactory = thrift.NewTTransportFactory() } if *thriftFramed { transportFactory = thrift.NewTFramedTransportFactory(transportFactory) } transportSocket, err := thrift.NewTSocket(*thriftAddr) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } transport := transportFactory.GetTransport(transportSocket) if err := transport.Open(); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } defer transport.Close() client := thriftadd.NewAddServiceClientFactory(transport, protocolFactory) service = thriftclient.New(client) } else { fmt.Fprintf(os.Stderr, "error: no remote address specified\n") os.Exit(1) } if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } switch *method { case "sum": a, _ := strconv.ParseInt(flag.Args()[0], 10, 64) b, _ := strconv.ParseInt(flag.Args()[1], 10, 64) v, err := service.Sum(context.Background(), int(a), int(b)) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } fmt.Fprintf(os.Stdout, "%d + %d = %d\n", a, b, v) case "concat": a := flag.Args()[0] b := flag.Args()[1] v, err := service.Concat(context.Background(), a, b) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } fmt.Fprintf(os.Stdout, "%q + %q = %q\n", a, b, v) default: fmt.Fprintf(os.Stderr, "error: invalid method %q\n", method) os.Exit(1) } }