mirror of
https://github.com/nats-io/nats.go.git
synced 2025-10-26 18:10:25 +08:00
Merge branch 'main' of https://github.com/nats-io/nats.go into jsv2
Improve readme Signed-off-by: Piotr Piotrowski <piotr@synadia.com> Fix msg size calculation Signed-off-by: Piotr Piotrowski <piotr@synadia.com> Add connection event listeners Signed-off-by: Piotr Piotrowski <piotr@synadia.com> Fix leaky goroutines in tests Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
This commit is contained in:
1
go.mod
1
go.mod
@@ -8,6 +8,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
golang.org/x/crypto v0.6.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
)
|
||||
|
||||
2
go.sum
2
go.sum
@@ -1,3 +1,5 @@
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA=
|
||||
github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
|
||||
12
go_test.mod
12
go_test.mod
@@ -4,7 +4,8 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/nats-io/nats-server/v2 v2.9.6
|
||||
github.com/klauspost/compress v1.16.5
|
||||
github.com/nats-io/nats-server/v2 v2.9.16
|
||||
github.com/nats-io/nkeys v0.4.4
|
||||
github.com/nats-io/nuid v1.0.1
|
||||
golang.org/x/text v0.3.6
|
||||
@@ -12,10 +13,9 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/klauspost/compress v1.15.11 // indirect
|
||||
github.com/minio/highwayhash v1.0.2 // indirect
|
||||
github.com/nats-io/jwt/v2 v2.3.0 // indirect
|
||||
golang.org/x/crypto v0.6.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
|
||||
github.com/nats-io/jwt/v2 v2.4.1 // indirect
|
||||
golang.org/x/crypto v0.8.0 // indirect
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
)
|
||||
|
||||
33
go_test.sum
33
go_test.sum
@@ -9,34 +9,25 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
|
||||
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
|
||||
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI=
|
||||
github.com/nats-io/jwt/v2 v2.3.0/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k=
|
||||
github.com/nats-io/nats-server/v2 v2.9.6 h1:RTtK+rv/4CcliOuqGsy58g7MuWkBaWmF5TUNwuUo9Uw=
|
||||
github.com/nats-io/nats-server/v2 v2.9.6/go.mod h1:AB6hAnGZDlYfqb7CTAm66ZKMZy9DpfierY1/PbpvI2g=
|
||||
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
|
||||
github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
|
||||
github.com/nats-io/jwt/v2 v2.4.1/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
|
||||
github.com/nats-io/nats-server/v2 v2.9.16 h1:SuNe6AyCcVy0g5326wtyU8TdqYmcPqzTjhkHojAjprc=
|
||||
github.com/nats-io/nats-server/v2 v2.9.16/go.mod h1:z1cc5Q+kqJkz9mLUdlcSsdYnId4pyImHjNgoh6zxSC0=
|
||||
github.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA=
|
||||
github.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
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=
|
||||
|
||||
60
js.go
60
js.go
@@ -1660,8 +1660,14 @@ func (js *js) subscribe(subj, queue string, cb MsgHandler, ch chan *Msg, isSync,
|
||||
}
|
||||
|
||||
// If we are creating or updating let's process that request.
|
||||
consName := o.cfg.Name
|
||||
if shouldCreate {
|
||||
info, err := js.upsertConsumer(stream, cfg.Durable, ccreq.Config)
|
||||
if cfg.Durable != "" {
|
||||
consName = cfg.Durable
|
||||
} else if consName == "" {
|
||||
consName = getHash(nuid.Next())
|
||||
}
|
||||
info, err := js.upsertConsumer(stream, consName, ccreq.Config)
|
||||
if err != nil {
|
||||
var apiErr *APIError
|
||||
if ok := errors.As(err, &apiErr); !ok {
|
||||
@@ -1964,40 +1970,22 @@ func (sub *Subscription) resetOrderedConsumer(sseq uint64) {
|
||||
cfg.DeliverPolicy = DeliverByStartSequencePolicy
|
||||
cfg.OptStartSeq = sseq
|
||||
|
||||
ccSubj := fmt.Sprintf(apiLegacyConsumerCreateT, jsi.stream)
|
||||
j, err := json.Marshal(jsi.ccreq)
|
||||
js := jsi.js
|
||||
sub.mu.Unlock()
|
||||
|
||||
consName := nuid.Next()
|
||||
cinfo, err := js.upsertConsumer(jsi.stream, consName, cfg)
|
||||
if err != nil {
|
||||
pushErr(err)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := nc.Request(js.apiSubj(ccSubj), j, js.opts.wait)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrNoResponders) || errors.Is(err, ErrTimeout) {
|
||||
var apiErr *APIError
|
||||
if errors.Is(err, ErrJetStreamNotEnabled) || errors.Is(err, ErrTimeout) {
|
||||
// if creating consumer failed, retry
|
||||
return
|
||||
}
|
||||
pushErr(err)
|
||||
return
|
||||
}
|
||||
|
||||
var cinfo consumerResponse
|
||||
err = json.Unmarshal(resp.Data, &cinfo)
|
||||
if err != nil {
|
||||
pushErr(err)
|
||||
return
|
||||
}
|
||||
|
||||
if cinfo.Error != nil {
|
||||
if cinfo.Error.ErrorCode == JSErrCodeInsufficientResourcesErr {
|
||||
} else if errors.As(err, &apiErr) && apiErr.ErrorCode == JSErrCodeInsufficientResourcesErr {
|
||||
// retry for insufficient resources, as it may mean that client is connected to a running
|
||||
// server in cluster while the server hosting R1 JetStream resources is restarting
|
||||
return
|
||||
}
|
||||
pushErr(cinfo.Error)
|
||||
pushErr(err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2489,6 +2477,14 @@ func ConsumerMemoryStorage() SubOpt {
|
||||
})
|
||||
}
|
||||
|
||||
// ConsumerName sets the name for a consumer.
|
||||
func ConsumerName(name string) SubOpt {
|
||||
return subOptFn(func(opts *subOpts) error {
|
||||
opts.cfg.Name = name
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (sub *Subscription) ConsumerInfo() (*ConsumerInfo, error) {
|
||||
sub.mu.Lock()
|
||||
// TODO(dlc) - Better way to mark especially if we attach.
|
||||
@@ -3586,3 +3582,17 @@ func (st *StorageType) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Length of our hash used for named consumers.
|
||||
const nameHashLen = 8
|
||||
|
||||
// Computes a hash for the given `name`.
|
||||
func getHash(name string) string {
|
||||
sha := sha256.New()
|
||||
sha.Write([]byte(name))
|
||||
b := sha.Sum(nil)
|
||||
for i := 0; i < nameHashLen; i++ {
|
||||
b[i] = rdigits[int(b[i]%base)]
|
||||
}
|
||||
return string(b[:nameHashLen])
|
||||
}
|
||||
|
||||
@@ -369,7 +369,7 @@ func TestJetStreamOrderedConsumerDeleteAssets(t *testing.T) {
|
||||
t.Run("remove consumer, expect it to be recreated", func(t *testing.T) {
|
||||
createStream()
|
||||
|
||||
createConsSub, err := nc.SubscribeSync("$JS.API.CONSUMER.CREATE.OBJECT")
|
||||
createConsSub, err := nc.SubscribeSync("$JS.API.CONSUMER.CREATE.OBJECT.*.a")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
12
object.go
12
object.go
@@ -369,13 +369,19 @@ func (obs *obs) Put(meta *ObjectMeta, r io.Reader, opts ...ObjectOpt) (*ObjectIn
|
||||
return perr
|
||||
}
|
||||
|
||||
purgePartial := func() { obs.js.purgeStream(obs.stream, &StreamPurgeRequest{Subject: chunkSubj}) }
|
||||
|
||||
// Create our own JS context to handle errors etc.
|
||||
js, err := obs.js.nc.JetStream(PublishAsyncErrHandler(func(js JetStream, _ *Msg, err error) { setErr(err) }))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
purgePartial := func() {
|
||||
// wait until all pubs are complete or up to default timeout before attempting purge
|
||||
select {
|
||||
case <-js.PublishAsyncComplete():
|
||||
case <-time.After(obs.js.opts.wait):
|
||||
}
|
||||
obs.js.purgeStream(obs.stream, &StreamPurgeRequest{Subject: chunkSubj})
|
||||
}
|
||||
|
||||
m, h := NewMsg(chunkSubj), sha256.New()
|
||||
chunk, sent, total := make([]byte, meta.Opts.ChunkSize), 0, uint64(0)
|
||||
@@ -1208,7 +1214,7 @@ func (o *objResult) Read(p []byte) (n int, err error) {
|
||||
}
|
||||
}
|
||||
if o.err != nil {
|
||||
return 0, err
|
||||
return 0, o.err
|
||||
}
|
||||
if o.r == nil {
|
||||
return 0, io.EOF
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2012-2122 The NATS Authors
|
||||
// Copyright 2012-2023 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
@@ -8789,3 +8789,95 @@ func TestJetStreamStreamInfoAlternates(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestJetStreamSubscribeConsumerName(t *testing.T) {
|
||||
s := RunBasicJetStreamServer()
|
||||
defer shutdownJSServerAndRemoveStorage(t, s)
|
||||
|
||||
nc, js := jsClient(t, s)
|
||||
defer nc.Close()
|
||||
|
||||
var err error
|
||||
|
||||
// Create the stream using our client API.
|
||||
_, err = js.AddStream(&nats.StreamConfig{
|
||||
Name: "TEST",
|
||||
Subjects: []string{"foo", "bar", "baz", "foo.*"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
_, err = js.Publish("foo", []byte("first"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Lookup the stream for testing.
|
||||
_, err = js.StreamInfo("TEST")
|
||||
if err != nil {
|
||||
t.Fatalf("stream lookup failed: %v", err)
|
||||
}
|
||||
|
||||
sub, err := js.SubscribeSync("foo", nats.ConsumerName("my-ephemeral"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cinfo, err := sub.ConsumerInfo()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := cinfo.Config.Name
|
||||
expected := "my-ephemeral"
|
||||
if got != expected {
|
||||
t.Fatalf("Expected: %v, got: %v", expected, got)
|
||||
}
|
||||
// Confirm that this is a durable.
|
||||
got = cinfo.Config.Durable
|
||||
expected = ""
|
||||
if got != expected {
|
||||
t.Fatalf("Expected: %v, got: %v", expected, got)
|
||||
}
|
||||
_, err = sub.NextMsg(1 * time.Second)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// ConsumerName will be ignored in case a durable name has been set.
|
||||
sub, err = js.SubscribeSync("foo", nats.Durable("durable"), nats.ConsumerName("custom-name"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cinfo, err = sub.ConsumerInfo()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got = cinfo.Config.Name
|
||||
expected = "durable"
|
||||
if got != expected {
|
||||
t.Fatalf("Expected: %v, got: %v", expected, got)
|
||||
}
|
||||
got = cinfo.Config.Durable
|
||||
expected = "durable"
|
||||
if got != expected {
|
||||
t.Fatalf("Expected: %v, got: %v", expected, got)
|
||||
}
|
||||
_, err = sub.NextMsg(1 * time.Second)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Default Ephemeral name should be short like in the server.
|
||||
sub, err = js.SubscribeSync("foo", nats.ConsumerName(""))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cinfo, err = sub.ConsumerInfo()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedSize := 8
|
||||
result := len(cinfo.Config.Name)
|
||||
if result != expectedSize {
|
||||
t.Fatalf("Expected: %v, got: %v", expectedSize, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,8 @@ func TestNoRaceObjectContextOpt(t *testing.T) {
|
||||
expectOk(t, err)
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
|
||||
time.AfterFunc(100*time.Millisecond, cancel)
|
||||
time.AfterFunc(10*time.Millisecond, cancel)
|
||||
|
||||
time.AfterFunc(20*time.Millisecond, func() { shutdownJSServerAndRemoveStorage(t, s) })
|
||||
start = time.Now()
|
||||
_, err = obs.GetBytes("BLOB", nats.Context(ctx))
|
||||
expectErr(t, err)
|
||||
|
||||
16
ws.go
16
ws.go
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 The NATS Authors
|
||||
// Copyright 2021-2023 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
@@ -16,7 +16,6 @@ package nats
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
@@ -30,6 +29,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/klauspost/compress/flate"
|
||||
)
|
||||
|
||||
type wsOpCode int
|
||||
@@ -448,8 +449,12 @@ func (w *websocketWriter) Write(p []byte) (int, error) {
|
||||
} else {
|
||||
w.compressor.Reset(buf)
|
||||
}
|
||||
w.compressor.Write(p)
|
||||
w.compressor.Close()
|
||||
if n, err = w.compressor.Write(p); err != nil {
|
||||
return n, err
|
||||
}
|
||||
if err = w.compressor.Flush(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
b := buf.Bytes()
|
||||
p = b[:len(b)-4]
|
||||
}
|
||||
@@ -692,6 +697,9 @@ func (nc *Conn) wsEnqueueCloseMsgLocked(status int, payload string) {
|
||||
wr.cm = frame
|
||||
wr.cmDone = true
|
||||
nc.bw.flush()
|
||||
if c := wr.compressor; c != nil {
|
||||
c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (nc *Conn) wsEnqueueControlMsg(needsLock bool, frameType wsOpCode, payload []byte) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 The NATS Authors
|
||||
// Copyright 2021-2023 The NATS Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
@@ -15,7 +15,6 @@ package nats
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/binary"
|
||||
@@ -32,6 +31,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/klauspost/compress/flate"
|
||||
"github.com/nats-io/nats-server/v2/server"
|
||||
serverTest "github.com/nats-io/nats-server/v2/test"
|
||||
"github.com/nats-io/nuid"
|
||||
|
||||
Reference in New Issue
Block a user