Skip to content

Commit efc1c28

Browse files
prepare 2.2.0 release (#14)
1 parent aaab12c commit efc1c28

34 files changed

+1117
-649
lines changed

.circleci/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ jobs:
5858
mkdir -p $CIRCLE_ARTIFACTS
5959
make test | tee $CIRCLE_ARTIFACTS/report.txt
6060
61+
- run:
62+
name: Run tests (easyjson implementation)
63+
command: |
64+
make test-easyjson | tee -a $CIRCLE_ARTIFACTS/report.txt
65+
6166
- run:
6267
name: Process test results
6368
command: go-junit-report < $CIRCLE_ARTIFACTS/report.txt > $CIRCLE_TEST_REPORTS/junit.xml
@@ -109,6 +114,10 @@ jobs:
109114
command: |
110115
mkdir -p $CIRCLE_ARTIFACTS
111116
make benchmarks | tee $CIRCLE_ARTIFACTS/benchmarks.txt
117+
- run:
118+
name: Run benchmarks (easyjson implementation)
119+
command: |
120+
make benchmarks-easyjson | tee $CIRCLE_ARTIFACTS/benchmarks-easyjson.txt
112121
113122
- store_artifacts:
114123
path: /tmp/circle-artifacts

Makefile

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,27 @@ COVERAGE_ENFORCER_FLAGS=-skipcode "// COVERAGE" -packagestats -filestats -showco
1515
TEST_BINARY=./build/go-sdk-common.test
1616
ALLOCATIONS_LOG=./build/allocations.out
1717

18-
.PHONY: build clean test test-coverage lint
18+
EASYJSON_TAG=launchdarkly_easyjson
19+
20+
.PHONY: all build build-easyjson clean test test-easyjson test-coverage lint benchmarks benchmarks-easyjson benchmark-allocs
21+
22+
all: build build-easyjson
1923

2024
build:
2125
go build ./...
2226

27+
build-easyjson:
28+
go build -tags $(EASYJSON_TAG) ./...
29+
2330
clean:
2431
go clean
2532

2633
test: build
2734
go test -race -v ./...
2835

36+
test-easyjson: build-easyjson
37+
go test -tags $(EASYJSON_TAG) -race -v ./...
38+
2939
test-coverage: $(COVERAGE_PROFILE_RAW)
3040
if [ -z "$(which go-coverage-enforcer)" ]; then go install github.com/launchdarkly-labs/go-coverage-enforcer; fi
3141
go-coverage-enforcer $(COVERAGE_ENFORCER_FLAGS) -outprofile $(COVERAGE_PROFILE_FILTERED) $(COVERAGE_PROFILE_RAW)
@@ -41,6 +51,10 @@ benchmarks: build
4151
go test -benchmem '-run=^$$' '-bench=.*' ./... | tee build/benchmarks.out
4252
@if grep <build/benchmarks.out 'NoAlloc.*[1-9][0-9]* allocs/op'; then echo "Unexpected heap allocations detected in benchmarks!"; exit 1; fi
4353

54+
benchmarks-easyjson: build
55+
@mkdir -p ./build
56+
go test -tags $(EASYJSON_TAG) -benchmem '-run=^$$' '-bench=.*' ./... | tee build/benchmarks.out
57+
4458
# See CONTRIBUTING.md regarding the use of the benchmark-allocs target. Notes about this implementation:
4559
# 1. We precompile the test code because otherwise the allocation traces will include the actions of the compiler itself.
4660
# 2. "benchtime=3x" means the run count (b.N) is set to 3. Setting it to 1 would produce less redundant output, but the
@@ -50,7 +64,7 @@ benchmark-allocs:
5064
@if [ -z "$$BENCHMARK" ]; then echo "must specify BENCHMARK=" && exit 1; fi
5165
@mkdir -p ./build
5266
@echo Precompiling test code to $(TEST_BINARY)
53-
@go test -c -o $(TEST_BINARY) >/dev/null 2>&1
67+
@go test -c -o $(TEST_BINARY) $(BENCHMARK_PACKAGE) >/dev/null 2>&1
5468
@echo "Generating heap allocation traces in $(ALLOCATIONS_LOG) for benchmark(s): $$BENCHMARK"
5569
@echo "You should see some benchmark result output; if you do not, you may have misspelled the benchmark name/regex"
5670
@GODEBUG=allocfreetrace=1 $(TEST_BINARY) -test.run=none -test.bench=$$BENCHMARK -test.benchmem -test.benchtime=1x 2>$(ALLOCATIONS_LOG)

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Also, unlike `go-server-sdk` this does not have `server` in the name, because no
1616

1717
This version of the project has been tested with Go 1.14 and higher.
1818

19+
## Integration with easyjson
20+
21+
LaunchDarkly tools frequently read and write JSON data. By default, `go-sdk-common` uses LaunchDarkly's open-source JSON library [`go-jsonstream`](https://github.com/launchdarkly/go-jsonstream), which is considerably faster than Go's built-in `encoding/json` and does not depend on any third-party code. However, it can optionally integrate with the third-party library [`easyjson`](https://github.com/mailru/easyjson), which may be even faster in some cases, without requiring any changes in your code. To enable this, set the build tag `launchdarkly_easyjson` when you run `go build`, which both switches `go-jsonstream` to use `easyjson` internally and also generates `MarshalEasyJSON`/`UnmarshalEasyJSON` methods for each JSON-serializable type. The `easyjson` library is still under development and has some potential compatibility issues; see its documentation for more details.
22+
23+
If you do not set the `launchdarkly_easyjson` build tag, `go-sdk-common` does not use any code from `easyjson`.
24+
1925
## Learn more
2026

2127
Check out our [documentation](http://docs.launchdarkly.com) for in-depth instructions on configuring and using LaunchDarkly. You can also head straight to the [complete reference guide for the Go SDK](http://docs.launchdarkly.com/docs/go-sdk-reference), or the [generated API documentation](https://godoc.org/gopkg.in/launchdarkly/go-sdk-common.v2) for this project.

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ go 1.13
44

55
require (
66
github.com/launchdarkly/go-test-helpers/v2 v2.2.0
7+
github.com/mailru/easyjson v0.7.6
78
github.com/stretchr/testify v1.6.1
9+
gopkg.in/launchdarkly/go-jsonstream.v1 v1.0.0
810
)

go.sum

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
6+
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
57
github.com/launchdarkly/go-test-helpers/v2 v2.2.0 h1:L3kGILP/6ewikhzhdNkHy1b5y4zs50LueWenVF0sBbs=
68
github.com/launchdarkly/go-test-helpers/v2 v2.2.0/go.mod h1:L7+th5govYp5oKU9iN7To5PgznBuIjBPn+ejqKR0avw=
9+
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
10+
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
711
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
812
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9-
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
1013
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
1114
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
1215
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
1316
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1417
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
1518
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
19+
gopkg.in/launchdarkly/go-jsonstream.v1 v1.0.0 h1:YI6AtOY2+Q9pSdCWO99TnenKPzmpZftV/RFdsIJTw/I=
20+
gopkg.in/launchdarkly/go-jsonstream.v1 v1.0.0/go.mod h1:YefdBjfITIP8D9BJLVbssFctHkJnQXhv+TiRdTV0Jr4=
1621
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
1722
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
1823
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

jsonstream/json_buffer_benchmark_test.go

Lines changed: 0 additions & 166 deletions
This file was deleted.

jsonstream/json_buffer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func TestWriteDeeplyNestedStructures(t *testing.T) {
228228
assert.Equal(t, expected, string(bytes))
229229
}
230230

231-
func TestUsageErrors(t *testing.T) {
231+
func TestJSONBufferUsageErrors(t *testing.T) {
232232
shouldFail := func(name string, expectedPartialOutput string, action func(j *JSONBuffer)) {
233233
t.Run(name, func(t *testing.T) {
234234
j := NewJSONBuffer()

jsonstream/jwriter_adapter.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package jsonstream
2+
3+
import (
4+
"gopkg.in/launchdarkly/go-jsonstream.v1/jwriter"
5+
)
6+
7+
type bufferAdapter struct {
8+
jsonBuffer *JSONBuffer
9+
}
10+
11+
func (b *bufferAdapter) Write(data []byte) (int, error) {
12+
b.jsonBuffer.buf.Write(data)
13+
if err := b.jsonBuffer.GetError(); err != nil {
14+
return 0, err // COVERAGE: can't reproduce this condition in unit tests
15+
}
16+
return len(data), nil
17+
}
18+
19+
// WriteToJSONBufferThroughWriter is a convenience method that allows marshaling logic written against
20+
// the newer jsonstream API to be used with this deprecated package.
21+
func WriteToJSONBufferThroughWriter(writable jwriter.Writable, jsonBuffer *JSONBuffer) {
22+
jsonBuffer.beforeValue()
23+
b := bufferAdapter{jsonBuffer}
24+
w := jwriter.NewStreamingWriter(&b, 100)
25+
writable.WriteToJSONWriter(&w)
26+
_ = w.Flush()
27+
err := w.Error()
28+
if err != nil && jsonBuffer.err == nil {
29+
jsonBuffer.err = err
30+
}
31+
jsonBuffer.afterValue()
32+
}

jsonstream/jwriter_adapter_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package jsonstream
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"testing"
7+
8+
"gopkg.in/launchdarkly/go-jsonstream.v1/jwriter"
9+
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
type testBufferAdapterFunc func(*jwriter.Writer)
15+
16+
func TestWriteToJSONBufferThroughWriter(t *testing.T) {
17+
marshalFunc := testBufferAdapterFunc(func(w *jwriter.Writer) {
18+
arr := w.Array()
19+
for i := 0; i < 100; i++ {
20+
arr.String(fmt.Sprintf("value%d", i))
21+
}
22+
arr.End()
23+
})
24+
25+
var jb JSONBuffer
26+
WriteToJSONBufferThroughWriter(marshalFunc, &jb)
27+
require.NoError(t, jb.GetError())
28+
29+
jw := jwriter.NewWriter()
30+
marshalFunc(&jw)
31+
32+
bytes1, err := jb.Get()
33+
require.NoError(t, err)
34+
bytes2 := jw.Bytes()
35+
assert.Equal(t, string(bytes1), string(bytes2))
36+
}
37+
38+
func TestWriteToJSONBufferThroughWriterCopiesErrorState(t *testing.T) {
39+
fakeError := errors.New("sorry")
40+
marshalFunc := testBufferAdapterFunc(func(w *jwriter.Writer) {
41+
w.AddError(fakeError)
42+
})
43+
44+
var jb JSONBuffer
45+
WriteToJSONBufferThroughWriter(marshalFunc, &jb)
46+
require.Equal(t, fakeError, jb.GetError())
47+
}
48+
49+
func (t testBufferAdapterFunc) WriteToJSONWriter(w *jwriter.Writer) {
50+
t(w)
51+
}

jsonstream/package_info.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Package jsonstream provides a fast JSON encoder for manual generation of sequential output.
1+
// Package jsonstream is a deprecated implementation of sequential JSON encoding and tokenizing.
22
//
3-
// This implementation is used by the LaunchDarkly Go SDK to avoid the overhead of reflection-based
4-
// marshalling.
3+
// Deprecated: this implementation is no longer used by the LaunchDarkly SDK, but is retained for backward
4+
// compatibility. It has been replaced by the go-jsonstream project: https://github.com/launchdarkly/go-jsonstream
55
package jsonstream

0 commit comments

Comments
 (0)