Example #1
0
func Benchmark_TChannel_YARPCToYARPC(b *testing.B) {
	serverCh, err := tchannel.NewChannel("server", nil)
	require.NoError(b, err, "failed to build server TChannel")

	serverCfg := yarpc.Config{
		Name:     "server",
		Inbounds: []transport.Inbound{ytchannel.NewInbound(serverCh)},
	}

	clientCh, err := tchannel.NewChannel("client", nil)
	require.NoError(b, err, "failed to build client TChannel")

	// no defer close on channels because YARPC will take care of that

	withDispatcher(b, serverCfg, func(server yarpc.Dispatcher) {
		server.Register(raw.Procedure("echo", yarpcEcho))

		// Need server already started to build client config
		clientCfg := yarpc.Config{
			Name: "client",
			Outbounds: yarpc.Outbounds{
				"server": {
					Unary: ytchannel.NewOutbound(clientCh, ytchannel.HostPort(serverCh.PeerInfo().HostPort)),
				},
			},
		}
		withDispatcher(b, clientCfg, func(client yarpc.Dispatcher) {
			b.ResetTimer()
			runYARPCClient(b, raw.New(client.Channel("server")))
		})
	})
}
Example #2
0
func Benchmark_TChannel_YARPCToTChannel(b *testing.B) {
	serverCh, err := tchannel.NewChannel("server", nil)
	require.NoError(b, err, "failed to build server TChannel")
	defer serverCh.Close()

	serverCh.Register(traw.Wrap(tchannelEcho{t: b}), "echo")
	require.NoError(b, serverCh.ListenAndServe(":0"), "failed to start up TChannel")

	clientCh, err := tchannel.NewChannel("client", nil)
	require.NoError(b, err, "failed to build client TChannel")

	clientCfg := yarpc.Config{
		Name: "client",
		Outbounds: yarpc.Outbounds{
			"server": {
				Unary: ytchannel.NewOutbound(clientCh, ytchannel.HostPort(serverCh.PeerInfo().HostPort)),
			},
		},
	}

	withDispatcher(b, clientCfg, func(client yarpc.Dispatcher) {
		b.ResetTimer()
		runYARPCClient(b, raw.New(client.Channel("server")))
	})
}
Example #3
0
// Run exercises a YARPC client against a tchannel server.
func Run(t crossdock.T) {
	fatals := crossdock.Fatals(t)

	encoding := t.Param(params.Encoding)
	server := t.Param(params.Server)
	serverHostPort := fmt.Sprintf("%v:%v", server, serverPort)

	ch, err := tchannel.NewChannel("yarpc-client", nil)
	fatals.NoError(err, "could not create channel")

	dispatcher := yarpc.NewDispatcher(yarpc.Config{
		Name: "yarpc-client",
		Outbounds: yarpc.Outbounds{
			serverName: {
				Unary: tch.NewOutbound(ch, tch.HostPort(serverHostPort)),
			},
		},
	})
	fatals.NoError(dispatcher.Start(), "could not start Dispatcher")
	defer dispatcher.Stop()

	switch encoding {
	case "raw":
		runRaw(t, dispatcher)
	case "json":
		runJSON(t, dispatcher)
	case "thrift":
		runThrift(t, dispatcher)
	default:
		fatals.Fail("", "unknown encoding %q", encoding)
	}
}
Example #4
0
// Create creates an RPC from the given parameters or fails the whole behavior.
func Create(t crossdock.T) yarpc.Dispatcher {
	fatals := crossdock.Fatals(t)

	server := t.Param(params.Server)
	fatals.NotEmpty(server, "server is required")

	var unaryOutbound transport.UnaryOutbound
	trans := t.Param(params.Transport)
	switch trans {
	case "http":
		unaryOutbound = ht.NewOutbound(fmt.Sprintf("http://%s:8081", server))
	case "tchannel":
		ch, err := tchannel.NewChannel("client", nil)
		fatals.NoError(err, "couldn't create tchannel")
		unaryOutbound = tch.NewOutbound(ch, tch.HostPort(server+":8082"))
	default:
		fatals.Fail("", "unknown transport %q", trans)
	}

	return yarpc.NewDispatcher(yarpc.Config{
		Name: "client",
		Outbounds: yarpc.Outbounds{
			"yarpc-test": {
				Unary: unaryOutbound,
			},
		},
	})
}
Example #5
0
// Phone implements the phone procedure
func Phone(ctx context.Context, reqMeta yarpc.ReqMeta, body *PhoneRequest) (*PhoneResponse, yarpc.ResMeta, error) {
	var outbound transport.UnaryOutbound

	switch {
	case body.Transport.HTTP != nil:
		t := body.Transport.HTTP
		url := fmt.Sprintf("http://%s:%d", t.Host, t.Port)
		outbound = ht.NewOutbound(url)
	case body.Transport.TChannel != nil:
		t := body.Transport.TChannel
		hostport := fmt.Sprintf("%s:%d", t.Host, t.Port)
		ch, err := tchannel.NewChannel("yarpc-test-client", nil)
		if err != nil {
			return nil, nil, fmt.Errorf("failed to build TChannel: %v", err)
		}
		outbound = tch.NewOutbound(ch, tch.HostPort(hostport))
	default:
		return nil, nil, fmt.Errorf("unconfigured transport")
	}

	if err := outbound.Start(transport.NoDeps); err != nil {
		return nil, nil, err
	}
	defer outbound.Stop()

	// TODO use reqMeta.Service for caller
	client := json.New(channel.MultiOutbound("yarpc-test", body.Service, transport.Outbounds{
		Unary: outbound,
	}))
	resBody := PhoneResponse{
		Service:   "yarpc-test", // TODO use reqMeta.Service
		Procedure: reqMeta.Procedure(),
	}

	ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
	defer cancel()
	_, err := client.Call(
		ctx,
		yarpc.NewReqMeta().Procedure(body.Procedure),
		body.Body,
		&resBody.Body)
	if err != nil {
		return nil, nil, err
	}

	return &resBody, nil, nil
}
Example #6
0
func (tt tchannelTransport) WithRegistry(r transport.Registry, f func(transport.UnaryOutbound)) {
	serverOpts := testutils.NewOpts().SetServiceName(testService)
	clientOpts := testutils.NewOpts().SetServiceName(testCaller)
	testutils.WithServer(tt.t, serverOpts, func(ch *tchannel.Channel, hostPort string) {
		i := tch.NewInbound(ch)
		require.NoError(tt.t, i.Start(transport.ServiceDetail{Name: testService, Registry: r}, transport.NoDeps), "failed to start")

		defer i.Stop()
		// ^ the server is already listening so this will just set up the
		// handler.

		client := testutils.NewClient(tt.t, clientOpts)
		o := tch.NewOutbound(client, tch.HostPort(hostPort))
		require.NoError(tt.t, o.Start(transport.NoDeps), "failed to start outbound")
		defer o.Stop()

		f(o)
	})
}
Example #7
0
func buildDispatcher(t crossdock.T) (dispatcher yarpc.Dispatcher, tconfig server.TransportConfig) {
	fatals := crossdock.Fatals(t)

	self := t.Param("ctxclient")
	subject := t.Param("ctxserver")
	fatals.NotEmpty(self, "ctxclient is required")
	fatals.NotEmpty(subject, "ctxserver is required")

	ch, err := tchannel.NewChannel("ctxclient", nil)
	fatals.NoError(err, "failed to create TChannel")

	var outbound transport.UnaryOutbound
	switch trans := t.Param(params.Transport); trans {
	case "http":
		outbound = ht.NewOutbound(fmt.Sprintf("http://%s:8081", subject))
		tconfig.TChannel = &server.TChannelTransport{Host: self, Port: 8087}
	case "tchannel":
		outbound = tch.NewOutbound(ch, tch.HostPort(fmt.Sprintf("%s:8082", subject)))
		tconfig.HTTP = &server.HTTPTransport{Host: self, Port: 8086}
	default:
		fatals.Fail("", "unknown transport %q", trans)
	}

	dispatcher = yarpc.NewDispatcher(yarpc.Config{
		Name: "ctxclient",
		Inbounds: []transport.Inbound{
			tch.NewInbound(ch, tch.ListenAddr(":8087")),
			ht.NewInbound(":8086"),
		},
		Outbounds: yarpc.Outbounds{
			"yarpc-test": {
				Unary: outbound,
			},
		},
	})

	return dispatcher, tconfig
}
Example #8
0
func createTChannelDispatcher(tracer opentracing.Tracer, t *testing.T) yarpc.Dispatcher {
	// Establish the TChannel
	ch, err := tchannel.NewChannel("yarpc-test", &tchannel.ChannelOptions{
		Tracer: tracer,
	})
	assert.NoError(t, err)
	hp := "127.0.0.1:4040"
	ch.ListenAndServe(hp)

	dispatcher := yarpc.NewDispatcher(yarpc.Config{
		Name: "yarpc-test",
		Inbounds: []transport.Inbound{
			ytchannel.NewInbound(ch),
		},
		Outbounds: yarpc.Outbounds{
			"yarpc-test": {
				Unary: ytchannel.NewOutbound(ch, ytchannel.HostPort(hp)),
			},
		},
		Tracer: tracer,
	})

	return dispatcher
}
Example #9
0
func main() {
	outboundName := ""
	flag.StringVar(
		&outboundName,
		"outbound", "", "name of the outbound to use (http/tchannel)",
	)

	flag.Parse()

	var outbound transport.UnaryOutbound
	switch strings.ToLower(outboundName) {
	case "http":
		outbound = http.NewOutbound("http://localhost:24034")
	case "tchannel":
		channel, err := tchannel.NewChannel("keyvalue-client", nil)
		if err != nil {
			log.Fatalln(err)
		}
		outbound = tch.NewOutbound(channel, tch.HostPort("localhost:28941"))
	default:
		log.Fatalf("invalid outbound: %q\n", outboundName)
	}

	cache := NewCacheFilter()
	dispatcher := yarpc.NewDispatcher(yarpc.Config{
		Name: "keyvalue-client",
		Outbounds: yarpc.Outbounds{
			"keyvalue": {
				Unary: outbound,
			},
		},
		Filter: cache,
	})
	if err := dispatcher.Start(); err != nil {
		log.Fatalf("failed to start Dispatcher: %v", err)
	}
	defer dispatcher.Stop()

	client := keyvalueclient.New(dispatcher.Channel("keyvalue"))

	scanner := bufio.NewScanner(os.Stdin)
	rootCtx := context.Background()
	for scanner.Scan() {
		line := scanner.Text()
		args := strings.Split(line, " ")
		if len(args) < 1 || len(args[0]) < 3 {
			continue
		}

		cmd := args[0]
		args = args[1:]

		switch cmd {

		case "get":
			if len(args) != 1 {
				fmt.Println("usage: get key")
				continue
			}
			key := args[0]

			ctx, cancel := context.WithTimeout(rootCtx, 100*time.Millisecond)
			defer cancel()

			if value, _, err := client.GetValue(ctx, nil, &key); err != nil {
				fmt.Printf("get %q failed: %s\n", key, err)
			} else {
				fmt.Println(key, "=", value)
			}
			continue

		case "set":
			if len(args) != 2 {
				fmt.Println("usage: set key value")
				continue
			}
			key, value := args[0], args[1]

			cache.Invalidate()
			ctx, cancel := context.WithTimeout(rootCtx, 100*time.Millisecond)
			defer cancel()

			if _, err := client.SetValue(ctx, nil, &key, &value); err != nil {
				fmt.Printf("set %q = %q failed: %v\n", key, value, err.Error())
			}
			continue

		case "exit":
			return

		default:
			fmt.Println("invalid command", cmd)
			fmt.Println("valid commansd are: get, set, exit")
		}
	}

	if err := scanner.Err(); err != nil {
		fmt.Println("error:", err.Error())
	}
}