internal/jsonrpc2: adding rpc trace tasks

Change-Id: I101957f7aeb95034a71ab2db47e0422721c500f6
Reviewed-on: https://go-review.googlesource.com/c/tools/+/179717
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/jsonrpc2/jsonrpc2.go b/internal/jsonrpc2/jsonrpc2.go
index 4735429..3796b44 100644
--- a/internal/jsonrpc2/jsonrpc2.go
+++ b/internal/jsonrpc2/jsonrpc2.go
@@ -11,6 +11,7 @@
 	"context"
 	"encoding/json"
 	"fmt"
+	"runtime/trace"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -103,6 +104,8 @@
 // It will return as soon as the notification has been sent, as no response is
 // possible.
 func (c *Conn) Notify(ctx context.Context, method string, params interface{}) error {
+	ctx, task := trace.NewTask(ctx, "jsonrpc2.Notify "+method)
+	defer task.End()
 	jsonParams, err := marshalToRaw(params)
 	if err != nil {
 		return fmt.Errorf("marshalling notify parameters: %v", err)
@@ -123,12 +126,15 @@
 // If the response is not an error, it will be decoded into result.
 // result must be of a type you an pass to json.Unmarshal.
 func (c *Conn) Call(ctx context.Context, method string, params, result interface{}) error {
+	ctx, task := trace.NewTask(ctx, "jsonrpc2.Call "+method)
+	defer task.End()
 	jsonParams, err := marshalToRaw(params)
 	if err != nil {
 		return fmt.Errorf("marshalling call parameters: %v", err)
 	}
 	// generate a new request identifier
 	id := ID{Number: atomic.AddInt64(&c.seq, 1)}
+	trace.Logf(ctx, "jsonrpc2", "request id %v", id)
 	request := &Request{
 		ID:     &id,
 		Method: method,
@@ -186,6 +192,8 @@
 // You must call this exactly once for any given request.
 // If err is set then result will be ignored.
 func (c *Conn) Reply(ctx context.Context, req *Request, result interface{}, err error) error {
+	ctx, task := trace.NewTask(ctx, "jsonrpc2.Reply "+req.Method)
+	defer task.End()
 	if req.IsNotify() {
 		return fmt.Errorf("reply not invoked with a valid call")
 	}
@@ -273,7 +281,12 @@
 			if e.ctx.Err() != nil {
 				continue
 			}
-			c.Handler(e.ctx, e.c, e.r)
+			ctx, task := trace.NewTask(e.ctx, "jsonrpc2.Handle "+e.r.Method)
+			if !e.r.IsNotify() {
+				trace.Logf(ctx, "jsonrpc2", "request id %v", e.r.ID)
+			}
+			c.Handler(ctx, e.c, e.r)
+			task.End()
 		}
 	}()
 	for {