diff --git a/conn.go b/conn.go index bd8471d..eb43b00 100644 --- a/conn.go +++ b/conn.go @@ -86,7 +86,7 @@ func (c *Conn) EntryErr(pri Priority, msg string, attrs []Attr) error { a = append(a, c.Common...) a = append(a, attrs...) err := c.WriteAttrs(a) - slices.Delete(a, 0, len(a)) // ensure GC doesn't see refs to old data + a = slices.Delete(a, 0, len(a)) // ensure GC doesn't see refs to old data c.atts.Put(a) return err } @@ -97,7 +97,7 @@ func (c *Conn) WriteAttrs(attrs []Attr) error { buf := c.bufs.Get().(*net.Buffers) *buf = (*buf)[:0] err := WireWrite(buf, c.s, attrs) - slices.Delete(*buf, 0, len(*buf)) // ensure GC doesn't see refs to old data + *buf = slices.Delete(*buf, 0, len(*buf)) // ensure GC doesn't see refs to old data c.bufs.Put(buf) return err } diff --git a/conn_test.go b/conn_test.go index 34bdffa..6c89a6a 100644 --- a/conn_test.go +++ b/conn_test.go @@ -4,6 +4,8 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "errors" + "fmt" "io" "net" "path/filepath" @@ -106,6 +108,10 @@ func checkWellFormedProto(buf []byte) (ok bool, pos int, desc string) { // Conn. func TestConcurrentEntries(t *testing.T) { c := testConnector(t) + const ( + numGoroutines = 16 + numEntries = 100 + ) // attributes which will be common to all EntryErr calls attr := make([]Attr, 0, 10 /* enough capacity to avoid realloc on append; might trigger data races */) @@ -118,20 +124,35 @@ func TestConcurrentEntries(t *testing.T) { // spawn goroutines start := make(chan struct{}) - for i := 0; i < 16; i++ { + result := make(chan error, numGoroutines) + for i := range numGoroutines { go func() { + var err error <-start - for j := 0; j < 100; j++ { - err := c.EntryErr(PriDebug, "message "+strconv.Itoa(i)+"."+strconv.Itoa(j), attr) + for j := range numEntries { + err = c.EntryErr(PriDebug, "message "+strconv.Itoa(i)+"."+strconv.Itoa(j), attr) if err != nil { - t.Fatalf("message %d.%d error: %v", i, j, err) + err = fmt.Errorf("message %d.%d error: %w", i, j, err) + break } } + result <- err }() } // try to get all the goroutines to start at roughly the same time close(start) + + // collect results + var errs []error + for range numGoroutines { + if err := <-result; err != nil { + errs = append(errs, err) + } + } + if err := errors.Join(errs...); err != nil { + t.Fatal(err) + } } // BenchmarkEntry is a benchmark for the common Entry function. diff --git a/go.mod b/go.mod index a721442..1124a22 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module src.lwithers.me.uk/go/journal -go 1.22.0 +go 1.25