Skip to content

Commit eea5ec3

Browse files
committed
Optimised meta snapshot encoding when GOEXPERIMENT=jsonv2 enabled
Signed-off-by: Neil Twigg <[email protected]>
1 parent 4363cea commit eea5ec3

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

scripts/runTestsOnTravis.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
set -ex
44

5+
export GOEXPERIMENT=jsonv2
6+
57
if [ "$1" = "compile" ]; then
68
# First check that NATS builds.
79
go build -v;

server/events.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ type ClientInfo struct {
315315
Name string `json:"name,omitempty"`
316316
Lang string `json:"lang,omitempty"`
317317
Version string `json:"ver,omitempty"`
318-
RTT time.Duration `json:"rtt,omitempty"`
318+
RTT time.Duration `json:"rtt,omitempty,format:units"`
319319
Server string `json:"server,omitempty"`
320320
Cluster string `json:"cluster,omitempty"`
321321
Alternates []string `json:"alts,omitempty"`

server/jetstream_cluster.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"strings"
3232
"sync/atomic"
3333
"time"
34+
"weak"
3435

3536
"github.com/klauspost/compress/s2"
3637
"github.com/minio/highwayhash"
@@ -69,6 +70,9 @@ type jetStreamCluster struct {
6970
peerStreamCancelMove *subscription
7071
// To pop out the monitorCluster before the raft layer.
7172
qch chan struct{}
73+
// Meta snapshot encode buffers. Weakly held so GC can collect at any time, but
74+
// can help us optimistically to reduce allocations on future snapshot calls.
75+
lastsnap weak.Pointer[bytes.Buffer] // nolint:unused
7276
}
7377

7478
// Used to track inflight stream add requests to properly re-use same group and sync subject.
@@ -1584,7 +1588,7 @@ func (js *jetStream) metaSnapshot() ([]byte, error) {
15841588

15851589
// Track how long it took to marshal the JSON
15861590
mstart := time.Now()
1587-
b, err := json.Marshal(streams)
1591+
b, err := js.metaSnapshotJSON(streams)
15881592
mend := time.Since(mstart)
15891593

15901594
js.mu.RUnlock()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2025 The NATS Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
//
14+
//go:build !goexperiment.jsonv2
15+
16+
package server
17+
18+
import (
19+
"encoding/json"
20+
)
21+
22+
func (js *jetStream) metaSnapshotJSON(streams []writeableStreamAssignment) ([]byte, error) {
23+
return json.Marshal(streams)
24+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2025 The NATS Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
//
14+
//go:build goexperiment.jsonv2
15+
16+
package server
17+
18+
import (
19+
"bytes"
20+
jsonv2 "encoding/json/v2"
21+
"weak"
22+
)
23+
24+
func (js *jetStream) metaSnapshotJSON(streams []writeableStreamAssignment) ([]byte, error) {
25+
b := js.cluster.lastsnap.Value()
26+
if b == nil {
27+
b = bytes.NewBuffer(nil)
28+
js.cluster.lastsnap = weak.Make(b)
29+
}
30+
b.Reset()
31+
if err := jsonv2.MarshalWrite(b, streams); err != nil {
32+
return nil, err
33+
}
34+
return b.Bytes(), nil
35+
}

0 commit comments

Comments
 (0)