Example #1
0
func main() {
	flag.Parse()

	channel, err := tchannel.NewChannel("worker", &tchannel.ChannelOptions{
	// Logger: tchannel.NewLevelLogger(tchannel.SimpleLogger, tchannel.LogLevelWarn),
	})
	if err != nil {
		log.Fatalf("could not create channel: %v", err)
	}

	worker := newWorker(*hostport, channel)
	server := thrift.NewServer(channel.GetSubChannel("pingpong"))
	server.Register(pingpong.NewTChanPingPongServer(worker))

	if err := channel.ListenAndServe(*hostport); err != nil {
		log.Fatalf("could not listen on hostport: %v", err)
	}

	bsopts := new(ringpop.BootstrapOptions)
	bsopts.File = *hostfile
	bsopts.Stopped = true
	if _, err := worker.ringpop.Bootstrap(bsopts); err != nil {
		log.Fatalf("could not bootstrap ringpop: %v", err)
	}

	// block
	select {}
}
Example #2
0
func setupBenchServer() ([]string, error) {
	ch, err := testutils.NewServerChannel(testutils.NewOpts().
		SetServiceName(benchServerName).
		SetFramePool(tchannel.NewSyncFramePool()))
	if err != nil {
		return nil, err
	}
	fmt.Println(benchServerName, "started on", ch.PeerInfo().HostPort)

	server := thrift.NewServer(ch)
	server.Register(gen.NewTChanSecondServiceServer(benchSecondHandler{}))

	if !*useHyperbahn {
		return []string{ch.PeerInfo().HostPort}, nil
	}

	// Set up a Hyperbahn client and advertise it.
	nodes := strings.Split(*hyperbahnNodes, ",")
	config := hyperbahn.Configuration{InitialNodes: nodes}
	hc, err := hyperbahn.NewClient(ch, config, nil)
	if err := hc.Advertise(); err != nil {
		return nil, err
	}

	return nodes, nil
}
Example #3
0
func (s *ForwarderTestSuite) registerPong(address string, channel *tchannel.Channel) {
	hmap := map[string]interface{}{
		"/ping": func(ctx json.Context, ping *Ping) (*Pong, error) {
			return &Pong{"Hello, world!", address}, nil
		},
		"/error": func(ctx json.Context, ping *Ping) (*Pong, error) {
			return nil, errors.New("remote error")
		},
	}
	s.Require().NoError(json.Register(channel, hmap, func(ctx context.Context, err error) {}))

	thriftHandler := &pingpong.MockTChanPingPong{}

	// successful request
	thriftHandler.On("Ping", mock.Anything, &pingpong.Ping{
		Key: "success",
	}).Return(&pingpong.Pong{
		Source: address,
	}, nil)

	// error request
	thriftHandler.On("Ping", mock.Anything, &pingpong.Ping{
		Key: "error",
	}).Return(nil, &pingpong.PingError{})

	server := thrift.NewServer(channel)
	server.Register(pingpong.NewTChanPingPongServer(thriftHandler))
}
Example #4
0
func TestThriftTracingPropagation(t *testing.T) {
	suite := &PropagationTestSuite{
		Encoding: EncodingInfo{Format: tchannel.Thrift, HeadersSupported: true},
		Register: func(t *testing.T, ch *tchannel.Channel) TracingCall {
			opts := &thrift.ClientOptions{HostPort: ch.PeerInfo().HostPort}
			thriftClient := thrift.NewClient(ch, ch.PeerInfo().ServiceName, opts)
			handler := &ThriftHandler{
				TraceHandler: TraceHandler{Ch: ch},
				t:            t,
				thriftClient: gen.NewTChanSimpleServiceClient(thriftClient),
			}

			// Register Thrift handler
			server := thrift.NewServer(ch)
			server.Register(gen.NewTChanSimpleServiceServer(handler))

			return handler.firstCall
		},
		TestCases: map[TracerType][]PropagationTestCase{
			Noop: {
				{ForwardCount: 2, TracingDisabled: true, ExpectedBaggage: "", ExpectedSpanCount: 0},
				{ForwardCount: 2, TracingDisabled: false, ExpectedBaggage: "", ExpectedSpanCount: 0},
			},
			Mock: {
				{ForwardCount: 2, TracingDisabled: true, ExpectedBaggage: BaggageValue, ExpectedSpanCount: 0},
				{ForwardCount: 2, TracingDisabled: false, ExpectedBaggage: BaggageValue, ExpectedSpanCount: 6},
			},
			Jaeger: {
				{ForwardCount: 2, TracingDisabled: true, ExpectedBaggage: BaggageValue, ExpectedSpanCount: 0},
				{ForwardCount: 2, TracingDisabled: false, ExpectedBaggage: BaggageValue, ExpectedSpanCount: 6},
			},
		},
	}
	suite.Run(t)
}
Example #5
0
// NewServer returns a new Server that can recieve Thrift calls or raw calls.
func NewServer(optFns ...Option) Server {
	opts := getOptions(optFns)
	if opts.external {
		return newExternalServer(opts)
	}

	ch, err := tchannel.NewChannel(opts.svcName, &tchannel.ChannelOptions{
		Logger: tchannel.NewLevelLogger(tchannel.NewLogger(os.Stderr), tchannel.LogLevelWarn),
	})
	if err != nil {
		panic("failed to create channel: " + err.Error())
	}
	if err := ch.ListenAndServe("127.0.0.1:0"); err != nil {
		panic("failed to listen on port 0: " + err.Error())
	}

	s := &internalServer{
		ch:   ch,
		opts: opts,
	}

	tServer := thrift.NewServer(ch)
	tServer.Register(gen.NewTChanSecondServiceServer(handler{calls: &s.thriftCalls}))
	ch.Register(raw.Wrap(rawHandler{calls: &s.rawCalls}), "echo")

	if len(opts.advertiseHosts) > 0 {
		if err := s.Advertise(opts.advertiseHosts); err != nil {
			panic("failed to advertise: " + err.Error())
		}
	}

	return s
}
Example #6
0
// Register the different endpoints of the test subject
func register(ch *tchannel.Channel) {
	ch.Register(raw.Wrap(echoRawHandler{}), "echo/raw")
	ch.Register(raw.Wrap(handlerTimeoutRawHandler{}), "handlertimeout/raw")

	json.Register(ch, json.Handlers{"echo": echoJSONHandler}, onError)

	tserver := thrift.NewServer(ch)
	tserver.Register(echo.NewTChanEchoServer(&echoThriftHandler{}))
	tserver.Register(gauntlet_tchannel.NewTChanThriftTestServer(&thriftTestHandler{}))
	tserver.Register(gauntlet_tchannel.NewTChanSecondServiceServer(&secondServiceHandler{}))
}
func setupServer(h *mocks.TChanTCollector) (*tchannel.Channel, error) {
	tchan, err := testutils.NewServer(&testutils.ChannelOpts{
		ServiceName: tcollectorServiceName,
	})
	if err != nil {
		return nil, err
	}

	server := thrift.NewServer(tchan)
	server.Register(gen.NewTChanTCollectorServer(h))
	return tchan, nil
}
Example #8
0
func SetupServer(t *testing.T, fn thrift.HealthFunc) (*tchannel.Channel, string) {
	_, cancel := tchannel.NewContext(time.Second * 10)
	defer cancel()

	opts := testutils.NewOpts().
		SetServiceName("testing").
		DisableLogVerification()
	tchan := testutils.NewServer(t, opts)

	if fn != nil {
		server := thrift.NewServer(tchan)
		server.RegisterHealthHandler(fn)
	}

	return tchan, tchan.PeerInfo().HostPort
}
Example #9
0
func setupServer() (net.Listener, error) {
	tchan, err := tchannel.NewChannel("server", optsFor("server"))
	if err != nil {
		return nil, err
	}

	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return nil, err
	}

	server := thrift.NewServer(tchan)
	server.Register(gen.NewTChanFirstServer(&firstHandler{}))
	server.Register(gen.NewTChanSecondServer(&secondHandler{}))

	// Serve will set the local peer info, and start accepting sockets in a separate goroutine.
	tchan.Serve(listener)
	return listener, nil
}
Example #10
0
func main() {
	// Create a TChannel and register the Thrift handlers.
	ch, err := tchannel.NewChannel("keyvalue", nil)
	if err != nil {
		log.Fatalf("Failed to create tchannel: %v", err)
	}

	// Register both the KeyValue and Admin services.
	// We can register multiple Thrift services on a single Hyperbahn service.
	h := newKVHandler()
	server := thrift.NewServer(ch)
	server.Register(keyvalue.NewTChanKeyValueServer(h))
	server.Register(keyvalue.NewTChanAdminServer(h))
	pprof.Register(ch)

	// Listen for connections on the external interface so we can receive connections.
	ip, err := tchannel.ListenIP()
	if err != nil {
		log.Fatalf("Failed to find IP to Listen on: %v", err)
	}
	// We use port 0 which asks the OS to assign any available port.
	// Static port allocations are not necessary for services on Hyperbahn.
	ch.ListenAndServe(fmt.Sprintf("%v:%v", ip, 0))

	// Advertising registers this service instance with Hyperbahn so
	// that Hyperbahn can route requests for "keyvalue" to us.
	config := hyperbahn.Configuration{InitialNodes: os.Args[1:]}
	if len(config.InitialNodes) == 0 {
		log.Fatalf("No Autobahn nodes to advertise with")
	}
	client, err := hyperbahn.NewClient(ch, config, nil)
	if err != nil {
		log.Fatalf("hyperbahn.NewClient failed: %v", err)
	}
	if err := client.Advertise(); err != nil {
		log.Fatalf("Hyperbahn advertise failed: %v", err)
	}

	// The service is now started up, run it till we receive a ctrl-c.
	log.Printf("KeyValue service has started on %v", ch.PeerInfo().HostPort)
	select {}
}
Example #11
0
// New returns a mock Hyperbahn server that can be used for testing.
func New() (*Mock, error) {
	ch, err := tchannel.NewChannel("hyperbahn", nil)
	if err != nil {
		return nil, err
	}

	mh := &Mock{
		ch:              ch,
		respCh:          make(chan int),
		discoverResults: make(map[string][]string),
	}
	if err := json.Register(ch, json.Handlers{"ad": mh.adHandler}, nil); err != nil {
		return nil, err
	}

	thriftServer := thrift.NewServer(ch)
	thriftServer.Register(hthrift.NewTChanHyperbahnServer(mh))

	return mh, ch.ListenAndServe("127.0.0.1:0")
}
Example #12
0
// New returns a mock Hyperbahn server that can be used for testing.
func New() (*Mock, error) {
	table := &mockTable{}
	ch, err := tchannel.NewChannel("hyperbahn", &tchannel.ChannelOptions{
		RelayHosts:         table,
		RelayLocalHandlers: []string{"hyperbahn"},
	})
	if err != nil {
		return nil, err
	}
	table.ch = ch
	mh := &Mock{
		ch:              ch,
		respCh:          make(chan int),
		discoverResults: make(map[string][]string),
	}
	if err := json.Register(ch, json.Handlers{"ad": mh.adHandler}, nil); err != nil {
		return nil, err
	}

	thriftServer := thrift.NewServer(ch)
	thriftServer.Register(hthrift.NewTChanHyperbahnServer(mh))

	return mh, ch.ListenAndServe("127.0.0.1:0")
}
Example #13
0
func (b *Behavior) registerThrift(ch *tchannel.Channel) {
	handler := &thriftHandler{b: b, ch: ch}
	server := thrift.NewServer(ch)
	server.Register(gen.NewTChanSimpleServiceServer(handler))
	b.thriftCall = handler.callDownstream
}
Example #14
0
func main() {
	flag.Parse()

	channel, err := tchannel.NewChannel("pingpong", &tchannel.ChannelOptions{})
	if err != nil {
		log.Fatalf("could not create channel: %v", err)
	}
	server := thrift.NewServer(channel)

	// The actual service implementation
	worker := newWorker(*hostport, channel)
	// wrap the PingPong worker by a ringpop adapter for routing RPC calls
	// NewRingpopPingPongAdapter is in the package containing the generated code
	// Its name is derived from the thrift service name as follows: `NewRingpop[Service Name]Adapter`
	adapter, err := gen.NewRingpopPingPongAdapter(worker, worker.ringpop, channel,
		// PingPongConfiguration contains the configuration for ringpop forwarding regaring this service
		// The name is derived as follows `[Service Name]Configuration`
		gen.PingPongConfiguration{
			// The ping member of the configuration refers to the Ping endpoint within the service.
			// Configuring an endpoint is optional and unconfigured endpoints will work but not be
			// forwarded to a different ringpop node during invocation
			// The name of the configuration struct passed in here is derived as follows:
			// `[Service Name][Endpoint Name]Configuration`
			Ping: &gen.PingPongPingConfiguration{
				// The configuration structs only member is the Key closure. The purpose of this closure
				// is to return the key used for ringpop sharding and forwarding. Calls that are sharded
				// on the same key are guaranteed to be forwarded to the same node.
				// The input signature for this closure is the same as the signature for your
				// implementation. The output is always the tuple (shardKey string, err error).
				Key: func(ctx thrift.Context, request *gen.Ping) (shardKey string, err error) {
					// The body of the Key closure can perform whatever logic is needed to come to a
					// meaningful shardKey for the the request
					if request == nil {
						return "", errors.New("missing request in call to Ping")
					}

					// Here we route the ping's for the same key to the same machine
					return request.Key, nil
				},
			},
		},
	)
	if err != nil {
		log.Fatalf("unable to wrap the worker: %q", err)
	}

	// now pass the ringpop adapter into the TChannel Thrift server for the PingPong Service
	server.Register(gen.NewTChanPingPongServer(adapter))

	if err := channel.ListenAndServe(*hostport); err != nil {
		log.Fatalf("could not listen on hostport: %v", err)
	}

	bsopts := new(swim.BootstrapOptions)
	bsopts.File = *hostfile
	bsopts.Stopped = true
	if _, err := worker.ringpop.Bootstrap(bsopts); err != nil {
		log.Fatalf("could not bootstrap ringpop: %v", err)
	}

	// block
	select {}
}
Example #15
0
func setupServer(t *testing.T, h *mocks.TChanTCollector) *tchannel.Channel {
	tchan := testutils.NewServer(t, testutils.NewOpts().SetServiceName(tcollectorServiceName))
	server := thrift.NewServer(tchan)
	server.Register(gen.NewTChanTCollectorServer(h))
	return tchan
}