1
0
mirror of https://github.com/golang/go synced 2024-09-30 20:28:32 -06:00
go/internal/jsonrpc2/serve.go
Rob Findley 66de428735 internal/jsonrpc2,internal/lsp/regtest: clean up some leaked tempfiles
Not all regtests resulted in LSP shutdown, which caused temp modfiles to
be leaked. After this fix I have confirmed that /tmp is clean after a
successful run of the regtests.

Also proactively clean up the unix socket file when serving jsonrpc2
over UDS.

Change-Id: I745fbd3d2adeeb165cadf7c54fd815d8df81d4e4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/220061
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rohan Challa <rohan@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2020-02-19 18:32:50 +00:00

73 lines
2.0 KiB
Go

// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package jsonrpc2
import (
"context"
"log"
"net"
"os"
)
// NOTE: This file provides an experimental API for serving multiple remote
// jsonrpc2 clients over the network. For now, it is intentionally similar to
// net/http, but that may change in the future as we figure out the correct
// semantics.
// A StreamServer is used to serve incoming jsonrpc2 clients communicating over
// a newly created stream.
type StreamServer interface {
ServeStream(context.Context, Stream) error
}
// The ServerFunc type is an adapter that implements the StreamServer interface
// using an ordinary function.
type ServerFunc func(context.Context, Stream) error
// ServeStream calls f(ctx, s).
func (f ServerFunc) ServeStream(ctx context.Context, s Stream) error {
return f(ctx, s)
}
// HandlerServer returns a StreamServer that handles incoming streams using the
// provided handler.
func HandlerServer(h Handler) StreamServer {
return ServerFunc(func(ctx context.Context, s Stream) error {
conn := NewConn(s)
conn.AddHandler(h)
return conn.Run(ctx)
})
}
// ListenAndServe starts an jsonrpc2 server on the given address. It exits only
// on error.
func ListenAndServe(ctx context.Context, network, addr string, server StreamServer) error {
ln, err := net.Listen(network, addr)
if err != nil {
return err
}
if network == "unix" {
defer os.Remove(addr)
}
return Serve(ctx, ln, server)
}
// Serve accepts incoming connections from the network, and handles them using
// the provided server. It exits only on error.
func Serve(ctx context.Context, ln net.Listener, server StreamServer) error {
for {
netConn, err := ln.Accept()
if err != nil {
return err
}
stream := NewHeaderStream(netConn, netConn)
go func() {
if err := server.ServeStream(ctx, stream); err != nil {
log.Printf("serving stream: %v", err)
}
}()
}
}