func main() { // Create a new TChannel for handling requests ch, err := tchannel.NewChannel("PingService", &tchannel.ChannelOptions{Logger: tchannel.SimpleLogger}) if err != nil { log.Fatalf("Could not create new channel: %v", err) } // Register a handler for the ping message on the PingService json.Register(ch, json.Handlers{ "ping": pingHandler, }, onError) // Listen for incoming requests listenAndHandle(ch, "127.0.0.1:10500") // Create a new TChannel for sending requests. client, err := tchannel.NewChannel("ping-client", nil) if err != nil { log.Fatalf("Could not create new client channel: %v", err) } // Make a call to ourselves, with a timeout of 10s ctx, cancel := json.NewContext(time.Second * 10) defer cancel() peer := client.Peers().Add(ch.PeerInfo().HostPort) var pong Pong if err := json.CallPeer(ctx, peer, "PingService", "ping", &Ping{"Hello World"}, &pong); err != nil { log.Fatalf("json.Call failed: %v", err) } log.Infof("Received pong: %s", pong.Message) // Create a new subchannel for the top-level channel subCh := ch.GetSubChannel("PingServiceOther") // Register a handler on the subchannel json.Register(subCh, json.Handlers{ "pingOther": pingOtherHandler, }, onError) // Try to send a message to the Service:Operation pair for the subchannel if err := json.CallPeer(ctx, peer, "PingServiceOther", "pingOther", &Ping{"Hello Other World"}, &pong); err != nil { log.Fatalf("json.Call failed: %v", err) } log.Infof("Received pong: %s", pong.Message) }
func TestTracingPropagates(t *testing.T) { WithVerifiedServer(t, nil, func(ch *Channel, hostPort string) { handler := &traceHandler{t: t, ch: ch} json.Register(ch, json.Handlers{ "call": handler.call, }, handler.onError) ctx, cancel := json.NewContext(time.Second) defer cancel() peer := ch.Peers().GetOrAdd(ch.PeerInfo().HostPort) var response TracingResponse require.NoError(t, json.CallPeer(ctx, peer, ch.PeerInfo().ServiceName, "call", &TracingRequest{ ForwardCount: 1, }, &response)) clientSpan := CurrentSpan(ctx) require.NotNil(t, clientSpan) assert.Equal(t, uint64(0), clientSpan.ParentID()) assert.Equal(t, uint64(0), clientSpan.ParentID()) assert.NotEqual(t, uint64(0), clientSpan.TraceID()) assert.Equal(t, clientSpan.TraceID(), response.TraceID) assert.Equal(t, clientSpan.SpanID(), response.ParentID) assert.Equal(t, response.TraceID, response.SpanID, "traceID = spanID for root span") nestedResponse := response.Child require.NotNil(t, nestedResponse) assert.Equal(t, clientSpan.TraceID(), nestedResponse.TraceID) assert.Equal(t, response.SpanID, nestedResponse.ParentID) assert.NotEqual(t, response.SpanID, nestedResponse.SpanID) }) }
func (h *traceHandler) call(ctx json.Context, req *TracingRequest) (*TracingResponse, error) { span := CurrentSpan(ctx) if span == nil { return nil, fmt.Errorf("tracing not found") } var childResp *TracingResponse if req.ForwardCount > 0 { sc := h.ch.Peers().GetOrAdd(h.ch.PeerInfo().HostPort) childResp = new(TracingResponse) require.NoError(h.t, json.CallPeer(ctx, sc, h.ch.PeerInfo().ServiceName, "call", nil, childResp)) } return &TracingResponse{ TraceID: span.TraceID(), SpanID: span.SpanID(), ParentID: span.ParentID(), Child: childResp, }, nil }