Skip to content

all: remove go.lsp.dev/pkg dependency #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ workflows:
context: org-global
matrix:
parameters:
go-version: ["1.16-buster"]
go-version: ["1.17-bullseye"]
pre-steps:
- setup
post-steps:
Expand All @@ -159,6 +159,6 @@ workflows:
context: org-global
matrix:
parameters:
go-version: ["1.16-buster"]
go-version: ["1.17-bullseye"]
pre-steps:
- setup
20 changes: 10 additions & 10 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ run:
skip-dirs: []
skip-dirs-use-default: true
skip-files: []
allow-parallel-runners: false
allow-parallel-runners: true

output:
format: colored-line-number
Expand All @@ -17,10 +17,10 @@ output:
linters-settings:
dupl:
threshold: 100
errcheck:
check-type-assertions: true
check-blank: true
exclude: .errcheckignore
# errcheck:
# check-type-assertions: true
# check-blank: true
# exclude: .errcheckignore
funlen:
lines: 100
statements: 60
Expand Down Expand Up @@ -54,7 +54,7 @@ linters-settings:
gofmt:
simplify: true
goimports:
local-prefixes: go.lsp.dev/jsonrpc2,go.lsp.dev
local-prefixes: go.lsp.dev/jsonrpc2
golint:
min-confidence: 0.3
govet:
Expand Down Expand Up @@ -96,6 +96,8 @@ linters-settings:
linters:
fast: false
disabled:
- deadcode # Finds unused code
- errcheck # Errcheck is a program for checking for unchecked errors in go programs
- exhaustivestruct # Checks if all struct's fields are initialized
- forbidigo # Forbids identifiers
- gci # Gci control golang package import order and make it always deterministic
Expand All @@ -105,23 +107,23 @@ linters:
- goerr113 # Golang linter to check the errors handling expressions
- gofumpt # Gofumpt checks whether code was gofumpt-ed
- goheader # Checks is file header matches to pattern
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes
- gomnd # An analyzer to detect magic numbers
- gomodguard # Allow and block list linter for direct Go module dependencies
- gosec # Inspects source code for security problems
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity
- paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test
- scopelint # Scopelint checks for unpinned variables in go programs
- sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed
- unparam # Reports unused function parameters
- wrapcheck # Checks that errors returned from external packages are wrapped TODO(zchee): enable
- wsl # Whitespace Linter
enable:
- asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers
- bodyclose # checks whether HTTP response body is closed successfully
- deadcode # Finds unused code
- depguard # Go linter that checks if package imports are in a list of acceptable packages
- dogsled # Checks assignments with too many blank identifiers
- dupl # Tool for code clone detection
- errcheck # Errcheck is a program for checking for unchecked errors in go programs
- errorlint # source code linter for Go software that can be used to find code that will cause problemswith the error wrapping scheme introduced in Go 1.13
- exhaustive # check exhaustiveness of enum switch statements
- exportloopref # checks for pointers to enclosing loop variables
Expand All @@ -133,7 +135,6 @@ linters:
- godot # Check if comments end in a period
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes
- goprintffuncname # Checks that printf-like functions are named with `f` at the end
- gosimple # Linter for Go source code that specializes in simplifying a code
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
Expand All @@ -157,7 +158,6 @@ linters:
- tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code
- unconvert # Remove unnecessary type conversions
- unparam # Reports unused function parameters
- unused # Checks Go code for unused constants, variables, functions and types
- varcheck # Finds unused global variables and constants
- whitespace # Tool for detection of leading and trailing whitespace
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ lint: fmt lint/golangci-lint ## Run all linters.
fmt: tools/bin/goimportz tools/bin/gofumpt ## Run goimportz and gofumpt.
$(call target)
find . -iname "*.go" -not -path "./vendor/**" | xargs -P ${JOBS} ${TOOLS_BIN}/goimportz -local=${PKG},$(subst /jsonrpc2,,$(PKG)) -w
find . -iname "*.go" -not -path "./vendor/**" | xargs -P ${JOBS} ${TOOLS_BIN}/gofumpt -s -extra -w
find . -iname "*.go" -not -path "./vendor/**" | xargs -P ${JOBS} ${TOOLS_BIN}/gofumpt -extra -w

.PHONY: lint/golangci-lint
lint/golangci-lint: tools/bin/golangci-lint .golangci.yml ## Run golangci-lint.
Expand Down
77 changes: 9 additions & 68 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ import (
"sync/atomic"

"github.com/segmentio/encoding/json"

"go.lsp.dev/pkg/event"
"go.lsp.dev/pkg/event/label"
"go.lsp.dev/pkg/event/tag"
)

// Conn is the common interface to jsonrpc clients and servers.
Expand Down Expand Up @@ -95,17 +91,6 @@ func (c *conn) Call(ctx context.Context, method string, params, result interface
return id, fmt.Errorf("marshaling call parameters: %w", err)
}

ctx, done := event.Start(ctx, method,
tag.Method.Of(method),
tag.RPCDirection.Of(tag.Outbound),
tag.RPCID.Of(fmt.Sprintf("%q", id)),
)
defer func() {
recordStatus(ctx, err)
done()
}()
event.Metric(ctx, tag.Started.Of(1))

// We have to add ourselves to the pending map before we send, otherwise we
// are racing the response. Also add a buffer to rchan, so that if we get a
// wire response between the time this call is cancelled and id is deleted
Expand All @@ -123,8 +108,7 @@ func (c *conn) Call(ctx context.Context, method string, params, result interface
}()

// now we are ready to send
n, err := c.write(ctx, call)
event.Metric(ctx, tag.SentBytes.Of(n))
_, err = c.write(ctx, call)
if err != nil {
// sending failed, we will never get a response, so don't leave it pending
return id, err
Expand Down Expand Up @@ -162,28 +146,13 @@ func (c *conn) Notify(ctx context.Context, method string, params interface{}) (e
return fmt.Errorf("marshaling notify parameters: %w", err)
}

ctx, done := event.Start(ctx, method,
tag.Method.Of(method),
tag.RPCDirection.Of(tag.Outbound),
)
defer func() {
recordStatus(ctx, err)
done()
}()

event.Metric(ctx, tag.Started.Of(1))
n, err := c.write(ctx, notify)
event.Metric(ctx, tag.SentBytes.Of(n))
_, err = c.write(ctx, notify)

return err
}

func (c *conn) replier(req Message, spanDone func()) Replier {
func (c *conn) replier(req Message) Replier {
return func(ctx context.Context, result interface{}, err error) error {
defer func() {
recordStatus(ctx, err)
spanDone()
}()
call, ok := req.(*Call)
if !ok {
// request was a notify, no need to respond
Expand All @@ -195,8 +164,7 @@ func (c *conn) replier(req Message, spanDone func()) Replier {
return err
}

n, err := c.write(ctx, response)
event.Metric(ctx, tag.SentBytes.Of(n))
_, err = c.write(ctx, response)
if err != nil {
// TODO(iancottrell): if a stream write fails, we really need to shut down the whole stream
return err
Expand All @@ -205,9 +173,9 @@ func (c *conn) replier(req Message, spanDone func()) Replier {
}
}

func (c *conn) write(ctx context.Context, msg Message) (n int64, err error) {
func (c *conn) write(ctx context.Context, msg Message) (int64, error) {
c.writeMu.Lock()
n, err = c.stream.Write(ctx, msg)
n, err := c.stream.Write(ctx, msg)
c.writeMu.Unlock()
if err != nil {
return 0, fmt.Errorf("write to stream: %w", err)
Expand All @@ -226,7 +194,7 @@ func (c *conn) run(ctx context.Context, handler Handler) {

for {
// get the next message
msg, n, err := c.stream.Read(ctx)
msg, _, err := c.stream.Read(ctx)
if err != nil {
// The stream failed, we cannot continue.
c.fail(err)
Expand All @@ -235,26 +203,8 @@ func (c *conn) run(ctx context.Context, handler Handler) {

switch msg := msg.(type) {
case Request:
labels := []label.Label{
tag.Method.Of(msg.Method()),
tag.RPCDirection.Of(tag.Inbound),
{}, // reserved for ID if present
}
if call, ok := msg.(*Call); ok {
labels[len(labels)-1] = tag.RPCID.Of(fmt.Sprintf("%q", call.ID()))
} else {
labels = labels[:len(labels)-1]
}

reqCtx, spanDone := event.Start(ctx, msg.Method(), labels...)
event.Metric(reqCtx,
tag.Started.Of(1),
tag.ReceivedBytes.Of(n),
)

if err := handler(reqCtx, c.replier(msg, spanDone), msg); err != nil {
// delivery failed, not much we can do
event.Error(reqCtx, "jsonrpc2 message delivery failed", err)
if err := handler(ctx, c.replier(msg), msg); err != nil {
c.fail(err)
}

case *Response:
Expand Down Expand Up @@ -293,12 +243,3 @@ func (c *conn) fail(err error) {
c.err.Store(err)
c.stream.Close()
}

// recordStatus records the status code based on the error.
func recordStatus(ctx context.Context, err error) {
if err != nil {
event.Label(ctx, tag.StatusCode.Of("ERROR"))
} else {
event.Label(ctx, tag.StatusCode.Of("OK"))
}
}
10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
module go.lsp.dev/jsonrpc2

go 1.16
go 1.17

replace go.lsp.dev/pkg => ../pkg

require github.com/segmentio/encoding v0.3.4

require (
github.com/segmentio/encoding v0.2.17
go.lsp.dev/pkg v0.0.0-20210125030640-b6310ac75a91
github.com/segmentio/asm v1.1.3 // indirect
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 // indirect
)
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
github.com/klauspost/cpuid/v2 v2.0.5 h1:qnfhwbFriwDIX51QncuNU5mEMf+6KE3t7O8V2KQl3Dg=
github.com/klauspost/cpuid/v2 v2.0.5/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/segmentio/encoding v0.2.17 h1:cgfmPc44u1po1lz5bSgF00gLCROBjDNc7h+H7I20zpc=
github.com/segmentio/encoding v0.2.17/go.mod h1:7E68jTSWMnNoYhHi1JbLd7NBSB6XfE4vzqhR88hDBQc=
go.lsp.dev/pkg v0.0.0-20210125030640-b6310ac75a91 h1:JPKNt/RzBcOc89rhZ4Vl6U05Y1nN37FAc8PTKE3hssk=
go.lsp.dev/pkg v0.0.0-20210125030640-b6310ac75a91/go.mod h1:gtSHRuYfbCT0qnbLnovpie/WEmqyJ7T4n6VXiFMBtcw=
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
github.com/segmentio/encoding v0.3.4 h1:WM4IBnxH8B9TakiM2QD5LyNl9JSndh88QbHqVC+Pauc=
github.com/segmentio/encoding v0.3.4/go.mod h1:n0JeuIqEQrQoPDGsjo8UNd1iA0U8d8+oHAA4E3G3OxM=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
8 changes: 1 addition & 7 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"context"
"fmt"
"sync"

"go.lsp.dev/pkg/event"
)

// Handler is invoked to handle incoming requests.
Expand Down Expand Up @@ -111,13 +109,9 @@ func AsyncHandler(handler Handler) (h Handler) {
return innerReply(ctx, result, err)
}

_, queueDone := event.Start(ctx, "queued")
go func() {
<-waitForPrevious
queueDone()
if err := handler(ctx, reply, req); err != nil {
event.Error(ctx, "jsonrpc2 async message delivery failed", err)
}
_ = handler(ctx, reply, req)
}()
return nil
})
Expand Down
31 changes: 3 additions & 28 deletions serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ package jsonrpc2

import (
"context"
"errors"
"fmt"
"io"
"net"
"os"
"time"

"go.lsp.dev/pkg/event"
)

// NOTE: This file provides an experimental API for serving multiple remote
Expand Down Expand Up @@ -114,10 +110,9 @@ func Serve(ctx context.Context, ln net.Listener, server StreamServer, idleTimeou
case err := <-doneListening:
return err

case err := <-closedConns:
if !isClosingError(err) {
event.Error(ctx, "closed a connection", err)
}
case <-closedConns:
// if !isClosingError(err) {
// }

activeConns--
if activeConns == 0 {
Expand All @@ -132,23 +127,3 @@ func Serve(ctx context.Context, ln net.Listener, server StreamServer, idleTimeou
}
}
}

// isClosingError reports whether the error occurs normally during the process of
// closing a network connection.
//
// It uses imperfect heuristics that err on the side of false negatives,
// and should not be used for anything critical.
func isClosingError(err error) bool {
if errors.Is(err, io.EOF) {
return true
}

// Per https://github.com/golang/go/issues/4373, this error string should not
// change. This is not ideal, but since the worst that could happen here is
// some superfluous logging, it is acceptable.
if err.Error() == "use of closed network connection" {
return true
}

return false
}
Loading