build(deps): bump github.com/nats-io/nats.go from 1.49.0 to 1.50.0
Bumps [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) from 1.49.0 to 1.50.0. - [Release notes](https://github.com/nats-io/nats.go/releases) - [Commits](https://github.com/nats-io/nats.go/compare/v1.49.0...v1.50.0) --- updated-dependencies: - dependency-name: github.com/nats-io/nats.go dependency-version: 1.50.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
d029201b83
commit
b78d3ed42b
@@ -56,7 +56,7 @@ require (
|
|||||||
github.com/mna/pigeon v1.3.0
|
github.com/mna/pigeon v1.3.0
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||||
github.com/nats-io/nats-server/v2 v2.12.6
|
github.com/nats-io/nats-server/v2 v2.12.6
|
||||||
github.com/nats-io/nats.go v1.49.0
|
github.com/nats-io/nats.go v1.50.0
|
||||||
github.com/oklog/run v1.2.0
|
github.com/oklog/run v1.2.0
|
||||||
github.com/olekukonko/tablewriter v1.1.4
|
github.com/olekukonko/tablewriter v1.1.4
|
||||||
github.com/onsi/ginkgo v1.16.5
|
github.com/onsi/ginkgo v1.16.5
|
||||||
@@ -259,7 +259,7 @@ require (
|
|||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/juliangruber/go-intersect v1.1.0 // indirect
|
github.com/juliangruber/go-intersect v1.1.0 // indirect
|
||||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||||
github.com/klauspost/compress v1.18.4 // indirect
|
github.com/klauspost/compress v1.18.5 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||||
github.com/klauspost/crc32 v1.3.0 // indirect
|
github.com/klauspost/crc32 v1.3.0 // indirect
|
||||||
github.com/kovidgoyal/go-parallel v1.1.1 // indirect
|
github.com/kovidgoyal/go-parallel v1.1.1 // indirect
|
||||||
|
|||||||
@@ -721,8 +721,8 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF
|
|||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||||
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||||
@@ -904,8 +904,8 @@ github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
|
|||||||
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
|
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
|
||||||
github.com/nats-io/nats-server/v2 v2.12.6 h1:Egbx9Vl7Ch8wTtpXPGqbehkZ+IncKqShUxvrt1+Enc8=
|
github.com/nats-io/nats-server/v2 v2.12.6 h1:Egbx9Vl7Ch8wTtpXPGqbehkZ+IncKqShUxvrt1+Enc8=
|
||||||
github.com/nats-io/nats-server/v2 v2.12.6/go.mod h1:4HPlrvtmSO3yd7KcElDNMx9kv5EBJBnJJzQPptXlheo=
|
github.com/nats-io/nats-server/v2 v2.12.6/go.mod h1:4HPlrvtmSO3yd7KcElDNMx9kv5EBJBnJJzQPptXlheo=
|
||||||
github.com/nats-io/nats.go v1.49.0 h1:yh/WvY59gXqYpgl33ZI+XoVPKyut/IcEaqtsiuTJpoE=
|
github.com/nats-io/nats.go v1.50.0 h1:5zAeQrTvyrKrWLJ0fu02W3br8ym57qf7csDzgLOpcds=
|
||||||
github.com/nats-io/nats.go v1.49.0/go.mod h1:fDCn3mN5cY8HooHwE2ukiLb4p4G4ImmzvXyJt+tGwdw=
|
github.com/nats-io/nats.go v1.50.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
|
||||||
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
|
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
|
||||||
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
|
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
|
||||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||||
|
|||||||
+10
-1
@@ -31,6 +31,9 @@ builds:
|
|||||||
- mips64le
|
- mips64le
|
||||||
goarm:
|
goarm:
|
||||||
- 7
|
- 7
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
-
|
-
|
||||||
id: "s2d"
|
id: "s2d"
|
||||||
binary: s2d
|
binary: s2d
|
||||||
@@ -57,6 +60,9 @@ builds:
|
|||||||
- mips64le
|
- mips64le
|
||||||
goarm:
|
goarm:
|
||||||
- 7
|
- 7
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
-
|
-
|
||||||
id: "s2sx"
|
id: "s2sx"
|
||||||
binary: s2sx
|
binary: s2sx
|
||||||
@@ -84,6 +90,9 @@ builds:
|
|||||||
- mips64le
|
- mips64le
|
||||||
goarm:
|
goarm:
|
||||||
- 7
|
- 7
|
||||||
|
ignore:
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
-
|
-
|
||||||
@@ -91,7 +100,7 @@ archives:
|
|||||||
name_template: "s2-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
name_template: "s2-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||||
format_overrides:
|
format_overrides:
|
||||||
- goos: windows
|
- goos: windows
|
||||||
format: zip
|
formats: ['zip']
|
||||||
files:
|
files:
|
||||||
- unpack/*
|
- unpack/*
|
||||||
- s2/LICENSE
|
- s2/LICENSE
|
||||||
|
|||||||
+7
@@ -26,6 +26,12 @@ This package will support the current Go version and 2 versions back.
|
|||||||
Use the links above for more information on each.
|
Use the links above for more information on each.
|
||||||
|
|
||||||
# changelog
|
# changelog
|
||||||
|
|
||||||
|
* Feb 9th, 2026 [1.18.4](https://github.com/klauspost/compress/releases/tag/v1.18.4)
|
||||||
|
* gzhttp: Add zstandard to server handler wrapper https://github.com/klauspost/compress/pull/1121
|
||||||
|
* zstd: Add ResetWithOptions to encoder/decoder https://github.com/klauspost/compress/pull/1122
|
||||||
|
* gzhttp: preserve qvalue when extra parameters follow in Accept-Encoding by @analytically in https://github.com/klauspost/compress/pull/1116
|
||||||
|
|
||||||
* Jan 16th, 2026 [1.18.3](https://github.com/klauspost/compress/releases/tag/v1.18.3)
|
* Jan 16th, 2026 [1.18.3](https://github.com/klauspost/compress/releases/tag/v1.18.3)
|
||||||
* Downstream CVE-2025-61728. See [golang/go#77102](https://github.com/golang/go/issues/77102).
|
* Downstream CVE-2025-61728. See [golang/go#77102](https://github.com/golang/go/issues/77102).
|
||||||
|
|
||||||
@@ -691,3 +697,4 @@ This code is licensed under the same conditions as the original Go code. See LIC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -407,8 +407,8 @@ func histogramSplit(b []byte, h []uint16) {
|
|||||||
for i, t := range x {
|
for i, t := range x {
|
||||||
v0 := &h[t]
|
v0 := &h[t]
|
||||||
v1 := &h[y[i]]
|
v1 := &h[y[i]]
|
||||||
v3 := &h[w[i]]
|
|
||||||
v2 := &h[z[i]]
|
v2 := &h[z[i]]
|
||||||
|
v3 := &h[w[i]]
|
||||||
*v0++
|
*v0++
|
||||||
*v1++
|
*v1++
|
||||||
*v2++
|
*v2++
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !amd64
|
//go:build !amd64
|
||||||
// +build !amd64
|
|
||||||
|
|
||||||
package flate
|
package flate
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build amd64 && !appengine && !noasm && gc
|
//go:build amd64 && !appengine && !noasm && gc
|
||||||
// +build amd64,!appengine,!noasm,gc
|
|
||||||
|
|
||||||
// This file contains the specialisation of Decoder.Decompress4X
|
// This file contains the specialisation of Decoder.Decompress4X
|
||||||
// and Decoder.Decompress1X that use an asm implementation of thir main loops.
|
// and Decoder.Decompress1X that use an asm implementation of thir main loops.
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !amd64 || appengine || !gc || noasm
|
//go:build !amd64 || appengine || !gc || noasm
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
// This file contains a generic implementation of Decoder.Decompress4X.
|
// This file contains a generic implementation of Decoder.Decompress4X.
|
||||||
package huff0
|
package huff0
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build amd64 && !appengine && !noasm && gc
|
//go:build amd64 && !appengine && !noasm && gc
|
||||||
// +build amd64,!appengine,!noasm,gc
|
|
||||||
|
|
||||||
package cpuinfo
|
package cpuinfo
|
||||||
|
|
||||||
|
|||||||
-1
@@ -4,7 +4,6 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (!amd64 && !arm64) || appengine || !gc || noasm
|
//go:build (!amd64 && !arm64) || appengine || !gc || noasm
|
||||||
// +build !amd64,!arm64 appengine !gc noasm
|
|
||||||
|
|
||||||
package s2
|
package s2
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !appengine && !noasm && gc
|
//go:build !appengine && !noasm && gc
|
||||||
// +build !appengine,!noasm,gc
|
|
||||||
|
|
||||||
package s2
|
package s2
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !amd64 || appengine || !gc || noasm
|
//go:build !amd64 || appengine || !gc || noasm
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
package s2
|
package s2
|
||||||
|
|
||||||
|
|||||||
+1
@@ -78,6 +78,7 @@ func (b *blockEnc) initNewEncode() {
|
|||||||
b.recentOffsets = [3]uint32{1, 4, 8}
|
b.recentOffsets = [3]uint32{1, 4, 8}
|
||||||
b.litEnc.Reuse = huff0.ReusePolicyNone
|
b.litEnc.Reuse = huff0.ReusePolicyNone
|
||||||
b.coders.setPrev(nil, nil, nil)
|
b.coders.setPrev(nil, nil, nil)
|
||||||
|
b.dictLitEnc = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset will reset the block for a new encode, but in the same stream,
|
// reset will reset the block for a new encode, but in the same stream,
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ type fastBase struct {
|
|||||||
crc *xxhash.Digest
|
crc *xxhash.Digest
|
||||||
tmp [8]byte
|
tmp [8]byte
|
||||||
blk *blockEnc
|
blk *blockEnc
|
||||||
lastDictID uint32
|
lastDict *dict
|
||||||
lowMem bool
|
lowMem bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-5
@@ -479,10 +479,13 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {
|
|||||||
if d == nil {
|
if d == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
dictChanged := d != e.lastDict
|
||||||
// Init or copy dict table
|
// Init or copy dict table
|
||||||
if len(e.dictTable) != len(e.table) || d.id != e.lastDictID {
|
if len(e.dictTable) != len(e.table) || dictChanged {
|
||||||
if len(e.dictTable) != len(e.table) {
|
if len(e.dictTable) != len(e.table) {
|
||||||
e.dictTable = make([]prevEntry, len(e.table))
|
e.dictTable = make([]prevEntry, len(e.table))
|
||||||
|
} else {
|
||||||
|
clear(e.dictTable)
|
||||||
}
|
}
|
||||||
end := int32(len(d.content)) - 8 + e.maxMatchOff
|
end := int32(len(d.content)) - 8 + e.maxMatchOff
|
||||||
for i := e.maxMatchOff; i < end; i += 4 {
|
for i := e.maxMatchOff; i < end; i += 4 {
|
||||||
@@ -510,13 +513,14 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {
|
|||||||
offset: i + 3,
|
offset: i + 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastDictID = d.id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init or copy dict table
|
// Init or copy dict long table
|
||||||
if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {
|
if len(e.dictLongTable) != len(e.longTable) || dictChanged {
|
||||||
if len(e.dictLongTable) != len(e.longTable) {
|
if len(e.dictLongTable) != len(e.longTable) {
|
||||||
e.dictLongTable = make([]prevEntry, len(e.longTable))
|
e.dictLongTable = make([]prevEntry, len(e.longTable))
|
||||||
|
} else {
|
||||||
|
clear(e.dictLongTable)
|
||||||
}
|
}
|
||||||
if len(d.content) >= 8 {
|
if len(d.content) >= 8 {
|
||||||
cv := load6432(d.content, 0)
|
cv := load6432(d.content, 0)
|
||||||
@@ -538,8 +542,8 @@ func (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {
|
|||||||
off++
|
off++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastDictID = d.id
|
|
||||||
}
|
}
|
||||||
|
e.lastDict = d
|
||||||
// Reset table to initial state
|
// Reset table to initial state
|
||||||
copy(e.longTable[:], e.dictLongTable)
|
copy(e.longTable[:], e.dictLongTable)
|
||||||
|
|
||||||
|
|||||||
+9
-5
@@ -1102,10 +1102,13 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {
|
|||||||
if d == nil {
|
if d == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
dictChanged := d != e.lastDict
|
||||||
// Init or copy dict table
|
// Init or copy dict table
|
||||||
if len(e.dictTable) != len(e.table) || d.id != e.lastDictID {
|
if len(e.dictTable) != len(e.table) || dictChanged {
|
||||||
if len(e.dictTable) != len(e.table) {
|
if len(e.dictTable) != len(e.table) {
|
||||||
e.dictTable = make([]tableEntry, len(e.table))
|
e.dictTable = make([]tableEntry, len(e.table))
|
||||||
|
} else {
|
||||||
|
clear(e.dictTable)
|
||||||
}
|
}
|
||||||
end := int32(len(d.content)) - 8 + e.maxMatchOff
|
end := int32(len(d.content)) - 8 + e.maxMatchOff
|
||||||
for i := e.maxMatchOff; i < end; i += 4 {
|
for i := e.maxMatchOff; i < end; i += 4 {
|
||||||
@@ -1133,14 +1136,15 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {
|
|||||||
offset: i + 3,
|
offset: i + 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastDictID = d.id
|
|
||||||
e.allDirty = true
|
e.allDirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init or copy dict table
|
// Init or copy dict long table
|
||||||
if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {
|
if len(e.dictLongTable) != len(e.longTable) || dictChanged {
|
||||||
if len(e.dictLongTable) != len(e.longTable) {
|
if len(e.dictLongTable) != len(e.longTable) {
|
||||||
e.dictLongTable = make([]prevEntry, len(e.longTable))
|
e.dictLongTable = make([]prevEntry, len(e.longTable))
|
||||||
|
} else {
|
||||||
|
clear(e.dictLongTable)
|
||||||
}
|
}
|
||||||
if len(d.content) >= 8 {
|
if len(d.content) >= 8 {
|
||||||
cv := load6432(d.content, 0)
|
cv := load6432(d.content, 0)
|
||||||
@@ -1162,9 +1166,9 @@ func (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {
|
|||||||
off++
|
off++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastDictID = d.id
|
|
||||||
e.allDirty = true
|
e.allDirty = true
|
||||||
}
|
}
|
||||||
|
e.lastDict = d
|
||||||
|
|
||||||
// Reset table to initial state
|
// Reset table to initial state
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-2
@@ -1040,15 +1040,18 @@ func (e *doubleFastEncoder) Reset(d *dict, singleBlock bool) {
|
|||||||
// ResetDict will reset and set a dictionary if not nil
|
// ResetDict will reset and set a dictionary if not nil
|
||||||
func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {
|
func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {
|
||||||
allDirty := e.allDirty
|
allDirty := e.allDirty
|
||||||
|
dictChanged := d != e.lastDict
|
||||||
e.fastEncoderDict.Reset(d, singleBlock)
|
e.fastEncoderDict.Reset(d, singleBlock)
|
||||||
if d == nil {
|
if d == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init or copy dict table
|
// Init or copy dict table
|
||||||
if len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {
|
if len(e.dictLongTable) != len(e.longTable) || dictChanged {
|
||||||
if len(e.dictLongTable) != len(e.longTable) {
|
if len(e.dictLongTable) != len(e.longTable) {
|
||||||
e.dictLongTable = make([]tableEntry, len(e.longTable))
|
e.dictLongTable = make([]tableEntry, len(e.longTable))
|
||||||
|
} else {
|
||||||
|
clear(e.dictLongTable)
|
||||||
}
|
}
|
||||||
if len(d.content) >= 8 {
|
if len(d.content) >= 8 {
|
||||||
cv := load6432(d.content, 0)
|
cv := load6432(d.content, 0)
|
||||||
@@ -1065,7 +1068,6 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastDictID = d.id
|
|
||||||
allDirty = true
|
allDirty = true
|
||||||
}
|
}
|
||||||
// Reset table to initial state
|
// Reset table to initial state
|
||||||
|
|||||||
+4
-2
@@ -805,9 +805,11 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init or copy dict table
|
// Init or copy dict table
|
||||||
if len(e.dictTable) != len(e.table) || d.id != e.lastDictID {
|
if len(e.dictTable) != len(e.table) || d != e.lastDict {
|
||||||
if len(e.dictTable) != len(e.table) {
|
if len(e.dictTable) != len(e.table) {
|
||||||
e.dictTable = make([]tableEntry, len(e.table))
|
e.dictTable = make([]tableEntry, len(e.table))
|
||||||
|
} else {
|
||||||
|
clear(e.dictTable)
|
||||||
}
|
}
|
||||||
if true {
|
if true {
|
||||||
end := e.maxMatchOff + int32(len(d.content)) - 8
|
end := e.maxMatchOff + int32(len(d.content)) - 8
|
||||||
@@ -827,7 +829,7 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.lastDictID = d.id
|
e.lastDict = d
|
||||||
e.allDirty = true
|
e.allDirty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
@@ -138,11 +138,18 @@ func (e *Encoder) Reset(w io.Writer) {
|
|||||||
func (e *Encoder) ResetWithOptions(w io.Writer, opts ...EOption) error {
|
func (e *Encoder) ResetWithOptions(w io.Writer, opts ...EOption) error {
|
||||||
e.o.resetOpt = true
|
e.o.resetOpt = true
|
||||||
defer func() { e.o.resetOpt = false }()
|
defer func() { e.o.resetOpt = false }()
|
||||||
|
hadDict := e.o.dict != nil
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
if err := o(&e.o); err != nil {
|
if err := o(&e.o); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hasDict := e.o.dict != nil
|
||||||
|
if hadDict != hasDict {
|
||||||
|
// Dict presence changed — encoder type must be recreated.
|
||||||
|
e.state.encoder = nil
|
||||||
|
e.init = sync.Once{}
|
||||||
|
}
|
||||||
e.Reset(w)
|
e.Reset(w)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -448,6 +455,12 @@ func (e *Encoder) Close() error {
|
|||||||
if s.encoder == nil {
|
if s.encoder == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if s.w == nil {
|
||||||
|
if len(s.filling) == 0 && !s.headerWritten && !s.eofWritten && s.nInput == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("zstd: encoder has no writer")
|
||||||
|
}
|
||||||
err := e.nextBlock(true)
|
err := e.nextBlock(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(s.err, ErrEncoderClosed) {
|
if errors.Is(s.err, ErrEncoderClosed) {
|
||||||
|
|||||||
+1
@@ -42,6 +42,7 @@ func (o *encoderOptions) setDefault() {
|
|||||||
level: SpeedDefault,
|
level: SpeedDefault,
|
||||||
allLitEntropy: false,
|
allLitEntropy: false,
|
||||||
lowMem: false,
|
lowMem: false,
|
||||||
|
fullZero: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build amd64 && !appengine && !noasm && gc
|
//go:build amd64 && !appengine && !noasm && gc
|
||||||
// +build amd64,!appengine,!noasm,gc
|
|
||||||
|
|
||||||
package zstd
|
package zstd
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !amd64 || appengine || !gc || noasm
|
//go:build !amd64 || appengine || !gc || noasm
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
package zstd
|
package zstd
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build (!amd64 && !arm64) || appengine || !gc || purego || noasm
|
//go:build (!amd64 && !arm64) || appengine || !gc || purego || noasm
|
||||||
// +build !amd64,!arm64 appengine !gc purego noasm
|
|
||||||
|
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build amd64 && !appengine && !noasm && gc
|
//go:build amd64 && !appengine && !noasm && gc
|
||||||
// +build amd64,!appengine,!noasm,gc
|
|
||||||
|
|
||||||
// Copyright 2019+ Klaus Post. All rights reserved.
|
// Copyright 2019+ Klaus Post. All rights reserved.
|
||||||
// License information can be found in the LICENSE file.
|
// License information can be found in the LICENSE file.
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !amd64 || appengine || !gc || noasm
|
//go:build !amd64 || appengine || !gc || noasm
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
// Copyright 2019+ Klaus Post. All rights reserved.
|
// Copyright 2019+ Klaus Post. All rights reserved.
|
||||||
// License information can be found in the LICENSE file.
|
// License information can be found in the LICENSE file.
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build amd64 && !appengine && !noasm && gc
|
//go:build amd64 && !appengine && !noasm && gc
|
||||||
// +build amd64,!appengine,!noasm,gc
|
|
||||||
|
|
||||||
package zstd
|
package zstd
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
//go:build !amd64 || appengine || !gc || noasm
|
//go:build !amd64 || appengine || !gc || noasm
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
package zstd
|
package zstd
|
||||||
|
|
||||||
|
|||||||
+147
@@ -0,0 +1,147 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
Official Go client library for the NATS messaging system. Provides core pub/sub, request/reply, JetStream (streams, consumers, KV, object store), and a micro services framework. Module path: `github.com/nats-io/nats.go`.
|
||||||
|
|
||||||
|
## Build and Test Commands
|
||||||
|
|
||||||
|
This project uses a **dual module** setup: `go.mod` for production (minimal deps) and `go_test.mod` for testing (includes nats-server, protobuf). Always use `-modfile=go_test.mod` when running tests or any command that needs test dependencies.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build
|
||||||
|
go build ./...
|
||||||
|
|
||||||
|
# Run all tests (race detector + internal_testing tag, sequential)
|
||||||
|
go test -modfile=go_test.mod -race -v -p=1 ./... --failfast -vet=off -tags=internal_testing
|
||||||
|
|
||||||
|
# Run NoRace tests (must be run separately, without -race flag)
|
||||||
|
go test -modfile=go_test.mod -v -run=TestNoRace -p=1 ./... --failfast -vet=off
|
||||||
|
|
||||||
|
# Run a specific test
|
||||||
|
go test -modfile=go_test.mod -race -run TestName ./... -tags=internal_testing
|
||||||
|
|
||||||
|
# Run tests for a specific package
|
||||||
|
go test -modfile=go_test.mod -race ./jetstream/... --failfast
|
||||||
|
go test -modfile=go_test.mod -race ./micro/... --failfast
|
||||||
|
|
||||||
|
# Coverage
|
||||||
|
./scripts/cov.sh
|
||||||
|
|
||||||
|
# Formatting
|
||||||
|
go fmt ./...
|
||||||
|
|
||||||
|
# Vet
|
||||||
|
go vet -modfile=go_test.mod ./...
|
||||||
|
|
||||||
|
# Static analysis (as CI does it)
|
||||||
|
staticcheck -modfile=go_test.mod ./...
|
||||||
|
|
||||||
|
# Linting (golangci-lint runs only on jetstream/)
|
||||||
|
golangci-lint run --timeout 5m0s ./jetstream/...
|
||||||
|
|
||||||
|
# Spell check
|
||||||
|
find . -type f -name "*.go" | xargs misspell -error -locale US
|
||||||
|
|
||||||
|
# Update test dependencies (never change go.mod for test deps)
|
||||||
|
go mod tidy -modfile=go_test.mod
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Build Tags
|
||||||
|
|
||||||
|
- **`internal_testing`** -- Exposes internal test helpers (e.g., `AddMsgFilter`, `CloseTCPConn`) from `testing_internal.go`. Required for many tests in `./test/`.
|
||||||
|
- **`skip_no_race_tests`** -- Skips the NoRace tests. Used by coverage scripts.
|
||||||
|
- **`!race && !skip_no_race_tests`** -- NoRace tests in `test/norace_test.go` only run when the race detector is OFF.
|
||||||
|
- **`compat`** -- Compatibility tests in `test/compat_test.go`.
|
||||||
|
|
||||||
|
## CI Pipeline (ci.yaml)
|
||||||
|
|
||||||
|
1. **lint** -- `go fmt`, `go vet`, `staticcheck`, `misspell` (all packages), `golangci-lint` (jetstream only).
|
||||||
|
2. **test** -- Matrix of Go 1.24 and 1.25. Runs NoRace tests first (`-run=TestNoRace` without `-race`), then full race-enabled tests with `-tags=internal_testing`.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
nats.go # Core connection, pub/sub, request/reply (~6500 lines)
|
||||||
|
parser.go # Client-side protocol parser
|
||||||
|
ws.go # WebSocket transport support
|
||||||
|
js.go # Legacy JetStream API (deprecated, see jetstream/)
|
||||||
|
jsm.go # Legacy JetStream management
|
||||||
|
kv.go # Legacy KeyValue API
|
||||||
|
object.go # Legacy Object Store API
|
||||||
|
enc.go # EncodedConn (deprecated)
|
||||||
|
netchan.go # Go channel bindings
|
||||||
|
timer.go # Internal timer utilities
|
||||||
|
context.go # Context-aware request methods
|
||||||
|
nats_iter.go # Go 1.23+ iterator support (go:build go1.23)
|
||||||
|
testing_internal.go # Internal test hooks (go:build internal_testing)
|
||||||
|
|
||||||
|
jetstream/ # New JetStream API (preferred over legacy)
|
||||||
|
jetstream.go # Top-level JetStream interface
|
||||||
|
stream.go # Stream management
|
||||||
|
stream_config.go # Stream configuration types
|
||||||
|
consumer.go # Consumer management
|
||||||
|
consumer_config.go # Consumer configuration types
|
||||||
|
pull.go # Pull consumer implementation
|
||||||
|
push.go # Push consumer (deprecated)
|
||||||
|
ordered.go # Ordered consumer
|
||||||
|
publish.go # JetStream publish methods
|
||||||
|
kv.go # KeyValue store
|
||||||
|
object.go # Object store
|
||||||
|
message.go # JetStream message types
|
||||||
|
errors.go # JetStream error types
|
||||||
|
test/ # Integration tests (package test, uses nats-server)
|
||||||
|
|
||||||
|
micro/ # Micro services framework
|
||||||
|
service.go # Service interface and implementation
|
||||||
|
request.go # Request handling
|
||||||
|
test/ # Integration tests
|
||||||
|
|
||||||
|
internal/
|
||||||
|
parser/ # NATS protocol parser (used by core client)
|
||||||
|
syncx/ # Concurrent map utility
|
||||||
|
|
||||||
|
encoders/
|
||||||
|
builtin/ # Default encoders (JSON, GOB, string)
|
||||||
|
protobuf/ # Protocol Buffers encoder
|
||||||
|
|
||||||
|
test/ # Integration tests for core package (package test)
|
||||||
|
helper_test.go # Server setup helpers (RunDefaultServer, RunBasicJetStreamServer, etc.)
|
||||||
|
norace_test.go # Tests that cannot run with -race (build tag guarded)
|
||||||
|
js_internal_test.go # Tests requiring internal_testing tag
|
||||||
|
configs/ # NATS server config files for tests
|
||||||
|
|
||||||
|
bench/ # Benchmarking utilities
|
||||||
|
examples/ # Example command-line tools (nats-pub, nats-sub, etc.)
|
||||||
|
scripts/cov.sh # Coverage collection script
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Architecture
|
||||||
|
|
||||||
|
- **Root `nats_test.go`** (package `nats`) -- White-box unit tests with access to unexported internals.
|
||||||
|
- **`test/`** (package `test`) -- Black-box integration tests. Tests start an embedded nats-server using helpers from `test/helper_test.go`. These require `-modfile=go_test.mod` since nats-server is a test-only dependency.
|
||||||
|
- **`jetstream/test/`** (package `test`) -- Integration tests for the new JetStream API, also use embedded nats-server.
|
||||||
|
- **`micro/test/`** (package `test`) -- Integration tests for the micro services framework.
|
||||||
|
- **NoRace tests** -- Prefixed `TestNoRace*`, guarded by `//go:build !race && !skip_no_race_tests`. Must be run separately without `-race`.
|
||||||
|
- Tests always run with `-p=1` (no parallel packages) because they start embedded servers on shared ports.
|
||||||
|
|
||||||
|
## Code Conventions
|
||||||
|
|
||||||
|
- **License header** -- Every `.go` file starts with the Apache 2.0 license header (Copyright year range).
|
||||||
|
- **Error variables** -- Exported errors defined as `var Err... = errors.New("nats: ...")` in `nats.go`. JetStream errors in `jetstream/errors.go` follow the same pattern.
|
||||||
|
- **Options pattern** -- Connection options use functional options: `nats.Connect(url, nats.Name("myapp"), nats.MaxReconnects(5))`. JetStream and micro use similar patterns.
|
||||||
|
- **No external dependencies in production** -- Only `klauspost/compress`, `nkeys`, `nuid` in `go.mod`. Test deps (nats-server, protobuf) are isolated in `go_test.mod`. PRs adding dependencies are scrutinized heavily.
|
||||||
|
- **Commits require sign-off** -- Use `git commit -s` (DCO: `Signed-off-by`).
|
||||||
|
- **US English spelling** -- Enforced by `misspell -locale US` in CI.
|
||||||
|
- **Interface-driven design** -- JetStream and micro packages define interfaces (`JetStream`, `Stream`, `Consumer`, `Service`) with concrete unexported implementations.
|
||||||
|
|
||||||
|
## Key Types
|
||||||
|
|
||||||
|
- `nats.Conn` -- Core connection, handles all NATS protocol operations.
|
||||||
|
- `nats.Msg` -- Message type for pub/sub and request/reply.
|
||||||
|
- `nats.Subscription` -- Represents a subscription (sync, async, or channel-based).
|
||||||
|
- `jetstream.JetStream` -- Entry point for new JetStream API (created via `jetstream.New(nc)`).
|
||||||
|
- `jetstream.Stream`, `jetstream.Consumer` -- Stream and consumer management.
|
||||||
|
- `micro.Service` -- Micro service instance (created via `micro.AddService(nc, config)`).
|
||||||
+1
-1
@@ -23,7 +23,7 @@ A [Go](http://golang.org) client for the [NATS messaging system](https://nats.io
|
|||||||
go get github.com/nats-io/nats.go@latest
|
go get github.com/nats-io/nats.go@latest
|
||||||
|
|
||||||
# To get a specific version:
|
# To get a specific version:
|
||||||
go get github.com/nats-io/nats.go@v1.49.0
|
go get github.com/nats-io/nats.go@v1.50.0
|
||||||
|
|
||||||
# Note that the latest major version for NATS Server is v2:
|
# Note that the latest major version for NATS Server is v2:
|
||||||
go get github.com/nats-io/nats-server/v2@latest
|
go get github.com/nats-io/nats-server/v2@latest
|
||||||
|
|||||||
+12
-12
@@ -1,22 +1,22 @@
|
|||||||
module github.com/nats-io/nats.go
|
module github.com/nats-io/nats.go
|
||||||
|
|
||||||
go 1.24.0
|
go 1.25.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang/protobuf v1.4.2
|
github.com/golang/protobuf v1.5.4
|
||||||
github.com/klauspost/compress v1.18.2
|
github.com/klauspost/compress v1.18.5
|
||||||
github.com/nats-io/jwt/v2 v2.8.0
|
github.com/nats-io/jwt/v2 v2.8.1
|
||||||
github.com/nats-io/nats-server/v2 v2.12.3
|
github.com/nats-io/nats-server/v2 v2.12.6
|
||||||
github.com/nats-io/nkeys v0.4.12
|
github.com/nats-io/nkeys v0.4.15
|
||||||
github.com/nats-io/nuid v1.0.1
|
github.com/nats-io/nuid v1.0.1
|
||||||
google.golang.org/protobuf v1.23.0
|
google.golang.org/protobuf v1.33.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op // indirect
|
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op // indirect
|
||||||
github.com/google/go-tpm v0.9.7 // indirect
|
github.com/google/go-tpm v0.9.8 // indirect
|
||||||
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 // indirect
|
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 // indirect
|
||||||
golang.org/x/crypto v0.46.0 // indirect
|
golang.org/x/crypto v0.49.0 // indirect
|
||||||
golang.org/x/sys v0.39.0 // indirect
|
golang.org/x/sys v0.42.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.15.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
+22
-18
@@ -1,5 +1,5 @@
|
|||||||
github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op h1:Ucf+QxEKMbPogRO5guBNe5cgd9uZgfoJLOYs8WWhtjM=
|
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op h1:kpBdlEPbRvff0mDD1gk7o9BhI16b9p5yYAXRlidpqJE=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E=
|
github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
@@ -7,32 +7,34 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-tpm v0.9.7 h1:u89J4tUUeDTlH8xxC3CTW7OHZjbjKoHdQ9W7gCUhtxA=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
github.com/google/go-tpm v0.9.7/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
|
github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
|
||||||
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
|
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||||
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||||
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 h1:KGuD/pM2JpL9FAYvBrnBBeENKZNh6eNtjqytV6TYjnk=
|
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 h1:KGuD/pM2JpL9FAYvBrnBBeENKZNh6eNtjqytV6TYjnk=
|
||||||
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
|
github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
|
||||||
github.com/nats-io/jwt/v2 v2.8.0 h1:K7uzyz50+yGZDO5o772eRE7atlcSEENpL7P+b74JV1g=
|
github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
|
||||||
github.com/nats-io/jwt/v2 v2.8.0/go.mod h1:me11pOkwObtcBNR8AiMrUbtVOUGkqYjMQZ6jnSdVUIA=
|
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
|
||||||
github.com/nats-io/nats-server/v2 v2.12.3 h1:KRv+1n7lddMVgkJPQer+pt36TcO0ENxjilBmeWdjcHs=
|
github.com/nats-io/nats-server/v2 v2.12.6 h1:Egbx9Vl7Ch8wTtpXPGqbehkZ+IncKqShUxvrt1+Enc8=
|
||||||
github.com/nats-io/nats-server/v2 v2.12.3/go.mod h1:MQXjG9WjyXKz9koWzUc3jYUMKD8x3CLmTNy91IQQz3Y=
|
github.com/nats-io/nats-server/v2 v2.12.6/go.mod h1:4HPlrvtmSO3yd7KcElDNMx9kv5EBJBnJJzQPptXlheo=
|
||||||
github.com/nats-io/nkeys v0.4.12 h1:nssm7JKOG9/x4J8II47VWCL1Ds29avyiQDRn0ckMvDc=
|
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
|
||||||
github.com/nats-io/nkeys v0.4.12/go.mod h1:MT59A1HYcjIcyQDJStTfaOY6vhy9XTUjOFo+SVsvpBg=
|
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
|
||||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
||||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
@@ -41,3 +43,5 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
|||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||||
|
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
|
|||||||
+2
-2
@@ -500,8 +500,8 @@ func validateConsumerName(name string) error {
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
return fmt.Errorf("%w: name is required", ErrInvalidConsumerName)
|
return fmt.Errorf("%w: name is required", ErrInvalidConsumerName)
|
||||||
}
|
}
|
||||||
if strings.ContainsAny(name, ">*. /\\") {
|
if strings.ContainsAny(name, ">*. /\\\t\r\n") {
|
||||||
return fmt.Errorf("%w: '%s'", ErrInvalidConsumerName, name)
|
return fmt.Errorf("%w: %q", ErrInvalidConsumerName, name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-2
@@ -316,6 +316,22 @@ type (
|
|||||||
// MaxConsumers is the maximum number of consumers allowed for this
|
// MaxConsumers is the maximum number of consumers allowed for this
|
||||||
// account.
|
// account.
|
||||||
MaxConsumers int `json:"max_consumers"`
|
MaxConsumers int `json:"max_consumers"`
|
||||||
|
|
||||||
|
// MaxAckPending is the maximum number of outstanding ACKs any consumer
|
||||||
|
// may configure.
|
||||||
|
MaxAckPending int `json:"max_ack_pending"`
|
||||||
|
|
||||||
|
// MemoryMaxStreamBytes is is the maximum size any single memory based
|
||||||
|
// stream may be.
|
||||||
|
MemoryMaxStreamBytes int64 `json:"memory_max_stream_bytes"`
|
||||||
|
|
||||||
|
// StoreMaxStreamBytes is the maximum size any single storage based
|
||||||
|
// stream may be.
|
||||||
|
StoreMaxStreamBytes int64 `json:"storage_max_stream_bytes"`
|
||||||
|
|
||||||
|
// MaxBytesRequired indicates if max bytes is required to be set for
|
||||||
|
// streams in this account.
|
||||||
|
MaxBytesRequired bool `json:"max_bytes_required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
jetStream struct {
|
jetStream struct {
|
||||||
@@ -966,8 +982,8 @@ func validateStreamName(stream string) error {
|
|||||||
if stream == "" {
|
if stream == "" {
|
||||||
return ErrStreamNameRequired
|
return ErrStreamNameRequired
|
||||||
}
|
}
|
||||||
if strings.ContainsAny(stream, ">*. /\\") {
|
if strings.ContainsAny(stream, ">*. /\\\t\r\n") {
|
||||||
return fmt.Errorf("%w: '%s'", ErrInvalidStreamName, stream)
|
return fmt.Errorf("%w: %q", ErrInvalidStreamName, stream)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-4
@@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -170,15 +171,20 @@ type (
|
|||||||
// argument. It can be configured with the same options as Watch.
|
// argument. It can be configured with the same options as Watch.
|
||||||
WatchFiltered(ctx context.Context, keys []string, opts ...WatchOpt) (KeyWatcher, error)
|
WatchFiltered(ctx context.Context, keys []string, opts ...WatchOpt) (KeyWatcher, error)
|
||||||
|
|
||||||
// Keys will return all keys.
|
// Keys will return all keys, filtering out any duplicates.
|
||||||
// Deprecated: Use ListKeys instead to avoid memory issues.
|
// For large datasets, this can be memory-heavy as all keys are loaded
|
||||||
|
// into memory. Use ListKeys for a streaming alternative.
|
||||||
Keys(ctx context.Context, opts ...WatchOpt) ([]string, error)
|
Keys(ctx context.Context, opts ...WatchOpt) ([]string, error)
|
||||||
|
|
||||||
// ListKeys will return KeyLister, allowing to retrieve all keys from
|
// ListKeys will return KeyLister, allowing to retrieve all keys from
|
||||||
// the key value store in a streaming fashion (on a channel).
|
// the key value store in a streaming fashion (on a channel).
|
||||||
|
// Note: On buckets with a large number of keys and frequent writes,
|
||||||
|
// duplicate keys may be reported during listing.
|
||||||
ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error)
|
ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error)
|
||||||
|
|
||||||
// ListKeysFiltered returns a KeyLister for filtered keys in the bucket.
|
// ListKeysFiltered returns a KeyLister for filtered keys in the bucket.
|
||||||
|
// Note: On buckets with a large number of keys and frequent writes,
|
||||||
|
// duplicate keys may be reported during listing.
|
||||||
ListKeysFiltered(ctx context.Context, filters ...string) (KeyLister, error)
|
ListKeysFiltered(ctx context.Context, filters ...string) (KeyLister, error)
|
||||||
|
|
||||||
// History will return all historical values for the key (up to
|
// History will return all historical values for the key (up to
|
||||||
@@ -1363,7 +1369,7 @@ func (kv *kvs) WatchAll(ctx context.Context, opts ...WatchOpt) (KeyWatcher, erro
|
|||||||
return kv.Watch(ctx, AllKeys, opts...)
|
return kv.Watch(ctx, AllKeys, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys will return all keys.
|
// Keys will return all keys, filtering out any duplicates.
|
||||||
func (kv *kvs) Keys(ctx context.Context, opts ...WatchOpt) ([]string, error) {
|
func (kv *kvs) Keys(ctx context.Context, opts ...WatchOpt) ([]string, error) {
|
||||||
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
||||||
watcher, err := kv.WatchAll(ctx, opts...)
|
watcher, err := kv.WatchAll(ctx, opts...)
|
||||||
@@ -1382,7 +1388,8 @@ func (kv *kvs) Keys(ctx context.Context, opts ...WatchOpt) ([]string, error) {
|
|||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return nil, ErrNoKeysFound
|
return nil, ErrNoKeysFound
|
||||||
}
|
}
|
||||||
return keys, nil
|
slices.Sort(keys)
|
||||||
|
return slices.Compact(keys), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type keyLister struct {
|
type keyLister struct {
|
||||||
@@ -1391,6 +1398,8 @@ type keyLister struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListKeys will return all keys.
|
// ListKeys will return all keys.
|
||||||
|
// Note: On buckets with a large number of keys and frequent writes,
|
||||||
|
// duplicate keys may be reported during listing.
|
||||||
func (kv *kvs) ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error) {
|
func (kv *kvs) ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error) {
|
||||||
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
||||||
watcher, err := kv.WatchAll(ctx, opts...)
|
watcher, err := kv.WatchAll(ctx, opts...)
|
||||||
@@ -1418,6 +1427,8 @@ func (kv *kvs) ListKeys(ctx context.Context, opts ...WatchOpt) (KeyLister, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListKeysFiltered returns a KeyLister for filtered keys in the bucket.
|
// ListKeysFiltered returns a KeyLister for filtered keys in the bucket.
|
||||||
|
// Note: On buckets with a large number of keys and frequent writes,
|
||||||
|
// duplicate keys may be reported during listing.
|
||||||
func (kv *kvs) ListKeysFiltered(ctx context.Context, filters ...string) (KeyLister, error) {
|
func (kv *kvs) ListKeysFiltered(ctx context.Context, filters ...string) (KeyLister, error) {
|
||||||
watcher, err := kv.WatchFiltered(ctx, filters, IgnoreDeletes(), MetaOnly())
|
watcher, err := kv.WatchFiltered(ctx, filters, IgnoreDeletes(), MetaOnly())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+9
-3
@@ -116,22 +116,28 @@ func (c *orderedConsumer) Consume(handler MessageHandler, opts ...PullConsumeOpt
|
|||||||
c.subscription = sub
|
c.subscription = sub
|
||||||
internalHandler := func(serial int) func(msg Msg) {
|
internalHandler := func(serial int) func(msg Msg) {
|
||||||
return func(msg Msg) {
|
return func(msg Msg) {
|
||||||
|
c.Lock()
|
||||||
// handler is a noop if message was delivered for a consumer with different serial
|
// handler is a noop if message was delivered for a consumer with different serial
|
||||||
if serial != c.serial {
|
if serial != c.serial {
|
||||||
|
c.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
meta, err := msg.Metadata()
|
meta, err := msg.Metadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.errHandler(serial)(c.currentSub, err)
|
currentSub := c.currentSub
|
||||||
|
c.Unlock()
|
||||||
|
c.errHandler(serial)(currentSub, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dseq := meta.Sequence.Consumer
|
dseq := meta.Sequence.Consumer
|
||||||
if dseq != c.cursor.deliverSeq+1 {
|
if dseq != c.cursor.deliverSeq+1 {
|
||||||
|
c.Unlock()
|
||||||
c.errHandler(serial)(sub, errOrderedSequenceMismatch)
|
c.errHandler(serial)(sub, errOrderedSequenceMismatch)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.cursor.deliverSeq = dseq
|
c.cursor.deliverSeq = dseq
|
||||||
c.cursor.streamSeq = meta.Sequence.Stream
|
c.cursor.streamSeq = meta.Sequence.Stream
|
||||||
|
c.Unlock()
|
||||||
handler(msg)
|
handler(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,10 +377,10 @@ func (s *orderedSubscription) Drain() {
|
|||||||
if !s.closed.CompareAndSwap(0, 1) {
|
if !s.closed.CompareAndSwap(0, 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
s.consumer.Lock()
|
||||||
|
defer s.consumer.Unlock()
|
||||||
if s.consumer.currentSub != nil {
|
if s.consumer.currentSub != nil {
|
||||||
s.consumer.currentConsumer.Lock()
|
|
||||||
s.consumer.currentSub.Drain()
|
s.consumer.currentSub.Drain()
|
||||||
s.consumer.currentConsumer.Unlock()
|
|
||||||
}
|
}
|
||||||
close(s.done)
|
close(s.done)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -1085,6 +1085,10 @@ func (s *pullSubscription) cleanup() {
|
|||||||
if s.subscription == nil || !s.subscription.IsValid() {
|
if s.subscription == nil || !s.subscription.IsValid() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if s.consumer != nil {
|
||||||
|
nc := s.consumer.js.conn
|
||||||
|
nc.RemoveStatusListener(s.connStatusChanged)
|
||||||
|
}
|
||||||
if s.hbMonitor != nil {
|
if s.hbMonitor != nil {
|
||||||
s.hbMonitor.Stop()
|
s.hbMonitor.Stop()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -367,8 +367,10 @@ type Tier struct {
|
|||||||
|
|
||||||
// APIStats reports on API calls to JetStream for this account.
|
// APIStats reports on API calls to JetStream for this account.
|
||||||
type APIStats struct {
|
type APIStats struct {
|
||||||
Total uint64 `json:"total"`
|
Level int `json:"level"`
|
||||||
Errors uint64 `json:"errors"`
|
Total uint64 `json:"total"`
|
||||||
|
Errors uint64 `json:"errors"`
|
||||||
|
Inflight uint64 `json:"inflight,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountLimits includes the JetStream limits of the current account.
|
// AccountLimits includes the JetStream limits of the current account.
|
||||||
|
|||||||
+11
-4
@@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -68,10 +69,13 @@ type KeyValue interface {
|
|||||||
// WatchFiltered will watch for any updates to keys that match the keys
|
// WatchFiltered will watch for any updates to keys that match the keys
|
||||||
// argument. It can be configured with the same options as Watch.
|
// argument. It can be configured with the same options as Watch.
|
||||||
WatchFiltered(keys []string, opts ...WatchOpt) (KeyWatcher, error)
|
WatchFiltered(keys []string, opts ...WatchOpt) (KeyWatcher, error)
|
||||||
// Keys will return all keys.
|
// Keys will return all keys, filtering out any duplicates.
|
||||||
// Deprecated: Use ListKeys instead to avoid memory issues.
|
// For large datasets, this can be memory-heavy as all keys are loaded
|
||||||
|
// into memory. Use ListKeys for a streaming alternative.
|
||||||
Keys(opts ...WatchOpt) ([]string, error)
|
Keys(opts ...WatchOpt) ([]string, error)
|
||||||
// ListKeys will return all keys in a channel.
|
// ListKeys will return all keys in a channel.
|
||||||
|
// Note: On buckets with a large number of keys and frequent writes,
|
||||||
|
// duplicate keys may be reported during listing.
|
||||||
ListKeys(opts ...WatchOpt) (KeyLister, error)
|
ListKeys(opts ...WatchOpt) (KeyLister, error)
|
||||||
// History will return all historical values for the key.
|
// History will return all historical values for the key.
|
||||||
History(key string, opts ...WatchOpt) ([]KeyValueEntry, error)
|
History(key string, opts ...WatchOpt) ([]KeyValueEntry, error)
|
||||||
@@ -867,7 +871,7 @@ func (kv *kvs) PurgeDeletes(opts ...PurgeOpt) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys() will return all keys.
|
// Keys will return all keys, filtering out any duplicates.
|
||||||
func (kv *kvs) Keys(opts ...WatchOpt) ([]string, error) {
|
func (kv *kvs) Keys(opts ...WatchOpt) ([]string, error) {
|
||||||
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
||||||
watcher, err := kv.WatchAll(opts...)
|
watcher, err := kv.WatchAll(opts...)
|
||||||
@@ -886,7 +890,8 @@ func (kv *kvs) Keys(opts ...WatchOpt) ([]string, error) {
|
|||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return nil, ErrNoKeysFound
|
return nil, ErrNoKeysFound
|
||||||
}
|
}
|
||||||
return keys, nil
|
slices.Sort(keys)
|
||||||
|
return slices.Compact(keys), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type keyLister struct {
|
type keyLister struct {
|
||||||
@@ -895,6 +900,8 @@ type keyLister struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListKeys will return all keys.
|
// ListKeys will return all keys.
|
||||||
|
// Note: On buckets with a large number of keys and frequent writes,
|
||||||
|
// duplicate keys may be reported during listing.
|
||||||
func (kv *kvs) ListKeys(opts ...WatchOpt) (KeyLister, error) {
|
func (kv *kvs) ListKeys(opts ...WatchOpt) (KeyLister, error) {
|
||||||
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
opts = append(opts, IgnoreDeletes(), MetaOnly())
|
||||||
watcher, err := kv.WatchAll(opts...)
|
watcher, err := kv.WatchAll(opts...)
|
||||||
|
|||||||
+32
-5
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2012-2024 The NATS Authors
|
// Copyright 2012-2026 The NATS Authors
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
@@ -38,6 +38,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nats-io/nkeys"
|
"github.com/nats-io/nkeys"
|
||||||
@@ -48,7 +49,7 @@ import (
|
|||||||
|
|
||||||
// Default Constants
|
// Default Constants
|
||||||
const (
|
const (
|
||||||
Version = "1.49.0"
|
Version = "1.50.0"
|
||||||
DefaultURL = "nats://127.0.0.1:4222"
|
DefaultURL = "nats://127.0.0.1:4222"
|
||||||
DefaultPort = 4222
|
DefaultPort = 4222
|
||||||
DefaultMaxReconnect = 60
|
DefaultMaxReconnect = 60
|
||||||
@@ -150,6 +151,7 @@ var (
|
|||||||
ErrMaxConnectionsExceeded = errors.New("nats: server maximum connections exceeded")
|
ErrMaxConnectionsExceeded = errors.New("nats: server maximum connections exceeded")
|
||||||
ErrMaxAccountConnectionsExceeded = errors.New("nats: maximum account active connections exceeded")
|
ErrMaxAccountConnectionsExceeded = errors.New("nats: maximum account active connections exceeded")
|
||||||
ErrConnectionNotTLS = errors.New("nats: connection is not tls")
|
ErrConnectionNotTLS = errors.New("nats: connection is not tls")
|
||||||
|
ErrTLS = errors.New("nats: tls error")
|
||||||
ErrMaxSubscriptionsExceeded = errors.New("nats: server maximum subscriptions exceeded")
|
ErrMaxSubscriptionsExceeded = errors.New("nats: server maximum subscriptions exceeded")
|
||||||
ErrWebSocketHeadersAlreadySet = errors.New("nats: websocket connection headers already set")
|
ErrWebSocketHeadersAlreadySet = errors.New("nats: websocket connection headers already set")
|
||||||
ErrServerNotInPool = errors.New("nats: selected server is not in the pool")
|
ErrServerNotInPool = errors.New("nats: selected server is not in the pool")
|
||||||
@@ -2342,7 +2344,7 @@ func (nc *Conn) makeTLSConn() error {
|
|||||||
nc.conn = tls.Client(nc.conn, tlsCopy)
|
nc.conn = tls.Client(nc.conn, tlsCopy)
|
||||||
conn := nc.conn.(*tls.Conn)
|
conn := nc.conn.(*tls.Conn)
|
||||||
if err := conn.Handshake(); err != nil {
|
if err := conn.Handshake(); err != nil {
|
||||||
return err
|
return fmt.Errorf("%w: %w", ErrTLS, err)
|
||||||
}
|
}
|
||||||
nc.bindToNewConn()
|
nc.bindToNewConn()
|
||||||
return nil
|
return nil
|
||||||
@@ -2585,6 +2587,31 @@ func (nc *Conn) setup() {
|
|||||||
copy(pub, _HPUB_P_)
|
copy(pub, _HPUB_P_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tlsHandshakeEOF wraps an error with context when it occurs right after
|
||||||
|
// a completed TLS handshake, which typically indicates the remote side
|
||||||
|
// rejected the client certificate (e.g. an mTLS proxy like nginx).
|
||||||
|
// Depending on timing, the error may be io.EOF (read from closed conn)
|
||||||
|
// or a "broken pipe"/"connection reset" (write to closed conn).
|
||||||
|
func (nc *Conn) tlsHandshakeEOF(err error) error {
|
||||||
|
tlsConn, ok := nc.conn.(*tls.Conn)
|
||||||
|
if !ok || !tlsConn.ConnectionState().HandshakeComplete {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if errors.Is(err, io.EOF) || isConnClosedError(err) {
|
||||||
|
return fmt.Errorf("%w: connection closed by remote after TLS handshake: %w", ErrTLS, err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// isConnClosedError reports whether the error indicates the remote
|
||||||
|
// side closed the connection (broken pipe or connection reset).
|
||||||
|
// NOTE: On Windows, connection resets use WSAECONNRESET which may not
|
||||||
|
// match syscall.ECONNRESET. In that case, the error will not be
|
||||||
|
// detected here but will still be returned unwrapped by the caller.
|
||||||
|
func isConnClosedError(err error) bool {
|
||||||
|
return errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)
|
||||||
|
}
|
||||||
|
|
||||||
// Process a connected connection and initialize properly.
|
// Process a connected connection and initialize properly.
|
||||||
func (nc *Conn) processConnectInit() error {
|
func (nc *Conn) processConnectInit() error {
|
||||||
// Set our deadline for the whole connect process
|
// Set our deadline for the whole connect process
|
||||||
@@ -2605,14 +2632,14 @@ func (nc *Conn) processConnectInit() error {
|
|||||||
// Process the INFO protocol received from the server
|
// Process the INFO protocol received from the server
|
||||||
err := nc.processExpectedInfo()
|
err := nc.processExpectedInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nc.tlsHandshakeEOF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the CONNECT protocol along with the initial PING protocol.
|
// Send the CONNECT protocol along with the initial PING protocol.
|
||||||
// Wait for the PONG response (or any error that we get from the server).
|
// Wait for the PONG response (or any error that we get from the server).
|
||||||
err = nc.sendConnect()
|
err = nc.sendConnect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nc.tlsHandshakeEOF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the number of PING sent out
|
// Reset the number of PING sent out
|
||||||
|
|||||||
+17
@@ -85,6 +85,7 @@ type websocketReader struct {
|
|||||||
nl bool
|
nl bool
|
||||||
dc *wsDecompressor
|
dc *wsDecompressor
|
||||||
nc *Conn
|
nc *Conn
|
||||||
|
closeErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
type wsDecompressor struct {
|
type wsDecompressor struct {
|
||||||
@@ -202,6 +203,15 @@ func (r *websocketReader) Read(p []byte) (int, error) {
|
|||||||
return r.drainPending(p), nil
|
return r.drainPending(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a deferred close error (from a previous Read that
|
||||||
|
// had both data frames and a close frame), return it now that
|
||||||
|
// pending data has been drained.
|
||||||
|
if r.closeErr != nil {
|
||||||
|
err := r.closeErr
|
||||||
|
r.closeErr = nil
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
// Get some data from the underlying reader.
|
// Get some data from the underlying reader.
|
||||||
n, err := r.r.Read(p)
|
n, err := r.r.Read(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -285,6 +295,13 @@ func (r *websocketReader) Read(p []byte) (int, error) {
|
|||||||
if wsIsControlFrame(frameType) {
|
if wsIsControlFrame(frameType) {
|
||||||
pos, err = r.handleControlFrame(frameType, buf, pos, rem)
|
pos, err = r.handleControlFrame(frameType, buf, pos, rem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// If we already have pending data (e.g. a -ERR message
|
||||||
|
// that arrived before this close frame), defer the error
|
||||||
|
// so the pending data can be returned to the caller first.
|
||||||
|
if len(r.pending) > 0 {
|
||||||
|
r.closeErr = err
|
||||||
|
break
|
||||||
|
}
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
rem = 0
|
rem = 0
|
||||||
|
|||||||
Vendored
+4
-4
@@ -880,8 +880,8 @@ github.com/justinas/alice
|
|||||||
# github.com/kevinburke/ssh_config v1.2.0
|
# github.com/kevinburke/ssh_config v1.2.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/kevinburke/ssh_config
|
github.com/kevinburke/ssh_config
|
||||||
# github.com/klauspost/compress v1.18.4
|
# github.com/klauspost/compress v1.18.5
|
||||||
## explicit; go 1.23
|
## explicit; go 1.24
|
||||||
github.com/klauspost/compress
|
github.com/klauspost/compress
|
||||||
github.com/klauspost/compress/flate
|
github.com/klauspost/compress/flate
|
||||||
github.com/klauspost/compress/fse
|
github.com/klauspost/compress/fse
|
||||||
@@ -1177,8 +1177,8 @@ github.com/nats-io/nats-server/v2/server/stree
|
|||||||
github.com/nats-io/nats-server/v2/server/sysmem
|
github.com/nats-io/nats-server/v2/server/sysmem
|
||||||
github.com/nats-io/nats-server/v2/server/thw
|
github.com/nats-io/nats-server/v2/server/thw
|
||||||
github.com/nats-io/nats-server/v2/server/tpm
|
github.com/nats-io/nats-server/v2/server/tpm
|
||||||
# github.com/nats-io/nats.go v1.49.0
|
# github.com/nats-io/nats.go v1.50.0
|
||||||
## explicit; go 1.24.0
|
## explicit; go 1.25.0
|
||||||
github.com/nats-io/nats.go
|
github.com/nats-io/nats.go
|
||||||
github.com/nats-io/nats.go/encoders/builtin
|
github.com/nats-io/nats.go/encoders/builtin
|
||||||
github.com/nats-io/nats.go/internal/parser
|
github.com/nats-io/nats.go/internal/parser
|
||||||
|
|||||||
Reference in New Issue
Block a user