func (c *Connection) Notify(ctx context.Context, method string, params interface{}) error {
	notify, err := NewNotification(method, params)
	if err != nil {
		return errors.Errorf("marshaling notify parameters: %v", err)
	}
	ctx, done := event.Start(ctx, method,
		tag.Method.Of(method),
		tag.RPCDirection.Of(tag.Outbound),
	)
	event.Metric(ctx, tag.Started.Of(1))
	err = c.write(ctx, notify)
	switch {
	case err != nil:
		event.Label(ctx, tag.StatusCode.Of("ERROR"))
	default:
		event.Label(ctx, tag.StatusCode.Of("OK"))
	}
	done()
	return err
}
Notify invokes the target method but does not wait for a response.
The params will be marshaled to JSON before sending over the wire, and will
be handed to the method invoked.
package jsonrpc2
import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"sync/atomic"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/event"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/event/label"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/debug/tag"
	errors "golang.org/x/xerrors"
)
type Binder interface {
	Bind(context.Context, *Connection) (ConnectionOptions, error)
}
type ConnectionOptions struct {
	Framer Framer
	Preempter Preempter
	Handler Handler
}
type Connection struct {
	seq         int64  
	closer      io.Closer
	writerBox   chan Writer
	outgoingBox chan map[ID]chan<- *Response
	incomingBox chan map[ID]*incoming
	async       *async
}
type AsyncCall struct {
	id        ID
	response  chan *Response  
	resultBox chan asyncResult
	endSpan   func()  
}
type asyncResult struct {
	result []byte
	err    error
}
type incoming struct {
	request   *Request         
	baseCtx   context.Context  
	done      func()           
	handleCtx context.Context  
	cancel    func()           
}
func (o ConnectionOptions) Bind(context.Context, *Connection) (ConnectionOptions, error) {
	return o, nil
}
func newConnection(ctx context.Context, rwc io.ReadWriteCloser, binder Binder) (*Connection, error) {
	c := &Connection{
		closer:      rwc,
		writerBox:   make(chan Writer, 1),
		outgoingBox: make(chan map[ID]chan<- *Response, 1),
		incomingBox: make(chan map[ID]*incoming, 1),
		async:       newAsync(),
	}
	options, err := binder.Bind(ctx, c)
	if err != nil {
		return nil, err
	}
	if options.Framer == nil {
		options.Framer = HeaderFramer()
	}
	if options.Preempter == nil {
		options.Preempter = defaultHandler{}
	}
	if options.Handler == nil {
		options.Handler = defaultHandler{}
	}
	c.outgoingBox <- make(map[ID]chan<- *Response)
	c.incomingBox <- make(map[ID]*incoming)
	reader := options.Framer.Reader(rwc)
	readToQueue := make(chan *incoming)
	queueToDeliver := make(chan *incoming)
	go c.readIncoming(ctx, reader, readToQueue)
	go c.manageQueue(ctx, options.Preempter, readToQueue, queueToDeliver)
	go c.deliverMessages(ctx, options.Handler, queueToDeliver)
	c.writerBox <- options.Framer.Writer(rwc)
	return c, nil
}