func main() { channel, err := tchannel.NewChannel("keyvalue", nil) if err != nil { log.Fatalln(err) } dispatcher := yarpc.NewDispatcher(yarpc.Config{ Name: "keyvalue", Inbounds: []transport.Inbound{ tch.NewInbound(channel, tch.ListenAddr(":28941")), http.NewInbound(":24034"), }, Interceptor: yarpc.Interceptors(requestLogInterceptor{}), }) handler := handler{items: make(map[string]string)} dispatcher.Register(json.Procedure("get", handler.Get)) dispatcher.Register(json.Procedure("set", handler.Set)) if err := dispatcher.Start(); err != nil { fmt.Println("error:", err.Error()) os.Exit(1) } select {} }
func register(reg transport.Registrar) { reg.Register(raw.Procedure("echo/raw", EchoRaw)) reg.Register(json.Procedure("echo", EchoJSON)) reg.Register(echoserver.New(EchoThrift{})) reg.Register(thrifttestserver.New(thriftTest{})) reg.Register(secondserviceserver.New(secondService{})) reg.Register(json.Procedure("unexpected-error", UnexpectedError)) reg.Register(json.Procedure("bad-response", BadResponse)) reg.Register(json.Procedure("phone", Phone)) reg.Register(json.Procedure("sleep", Sleep)) reg.Register(raw.Procedure("sleep/raw", SleepRaw)) reg.Register(raw.Procedure("waitfortimeout/raw", WaitForTimeoutRaw)) }
func (h handler) register(dispatcher yarpc.Dispatcher) { dispatcher.Register(json.Procedure("echo", h.handleEcho)) dispatcher.Register(json.Procedure("echoecho", h.handleEchoEcho)) }
// Run verifies that opentracing context is propagated across multiple hops. // // Behavior parameters: // // - ctxclient: Address of this client. // - ctxserver: Address of the crossdock test subject server. // - transport: The transport to make requests to the test subject with. // // This behavior sets up a server in-process which the Phone procedure on the // test subject is responsible for calling. // // Outgoing calls to the Phone procedure will be made using the transport // specified as a parameter, and incoming calls from the Phone procedure will // be received over a different transport. func Run(t crossdock.T) { checks := crossdock.Checks(t) assert := crossdock.Assert(t) fatals := crossdock.Fatals(t) tests := []struct { desc string initCtx context.Context handlers map[string]handler procedure string }{ { desc: "no baggage", handlers: map[string]handler{ "hello": &singleHopHandler{ t: t, wantBaggage: map[string]string{}, }, }, }, { desc: "existing baggage", initCtx: func() context.Context { span := opentracing.GlobalTracer().StartSpan("existing baggage") span.SetBaggageItem("token", "42") return opentracing.ContextWithSpan(context.Background(), span) }(), handlers: map[string]handler{ "hello": &singleHopHandler{ t: t, wantBaggage: map[string]string{"token": "42"}, }, }, }, { desc: "add baggage", procedure: "one", handlers: map[string]handler{ "one": &multiHopHandler{ t: t, phoneCallTo: "two", addBaggage: map[string]string{"x": "1"}, wantBaggage: map[string]string{}, }, "two": &multiHopHandler{ t: t, phoneCallTo: "three", addBaggage: map[string]string{"y": "2"}, wantBaggage: map[string]string{"x": "1"}, }, "three": &singleHopHandler{ t: t, wantBaggage: map[string]string{"x": "1", "y": "2"}, }, }, }, { desc: "add baggage: existing baggage", initCtx: func() context.Context { span := opentracing.GlobalTracer().StartSpan("existing baggage") span.SetBaggageItem("token", "123") return opentracing.ContextWithSpan(context.Background(), span) }(), procedure: "one", handlers: map[string]handler{ "one": &multiHopHandler{ t: t, phoneCallTo: "two", addBaggage: map[string]string{"hello": "world"}, wantBaggage: map[string]string{"token": "123"}, }, "two": &singleHopHandler{ t: t, wantBaggage: map[string]string{"token": "123", "hello": "world"}, }, }, }, { desc: "overwrite baggage", initCtx: func() context.Context { span := opentracing.GlobalTracer().StartSpan("existing baggage") span.SetBaggageItem("x", "1") return opentracing.ContextWithSpan(context.Background(), span) }(), procedure: "one", handlers: map[string]handler{ "one": &multiHopHandler{ t: t, phoneCallTo: "two", addBaggage: map[string]string{"x": "2", "y": "3"}, wantBaggage: map[string]string{"x": "1"}, }, "two": &multiHopHandler{ t: t, phoneCallTo: "three", addBaggage: map[string]string{"y": "4"}, wantBaggage: map[string]string{"x": "2", "y": "3"}, }, "three": &singleHopHandler{ t: t, wantBaggage: map[string]string{"x": "2", "y": "4"}, }, }, }, } for _, tt := range tests { func() { procedure := tt.procedure if procedure == "" { if !assert.Len(tt.handlers, 1, "%v: invalid test: starting procedure must be provided", tt.desc) { return } for k := range tt.handlers { procedure = k } } dispatcher, tconfig := buildDispatcher(t) fatals.NoError(dispatcher.Start(), "%v: Dispatcher failed to start", tt.desc) defer dispatcher.Stop() jsonClient := json.New(dispatcher.Channel("yarpc-test")) for name, handler := range tt.handlers { handler.SetClient(jsonClient) handler.SetTransport(tconfig) dispatcher.Register(json.Procedure(name, handler.Handle)) } ctx := context.Background() if tt.initCtx != nil { ctx = tt.initCtx } ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() var resp js.RawMessage _, err := jsonClient.Call( ctx, yarpc.NewReqMeta().Procedure("phone"), &server.PhoneRequest{ Service: "ctxclient", Procedure: procedure, Transport: tconfig, Body: &js.RawMessage{'{', '}'}, }, &resp) checks.NoError(err, "%v: request failed", tt.desc) }() } }