Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package telemetrygen for openSUSE:Factory checked in at 2026-05-12 19:27:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/telemetrygen (Old) and /work/SRC/openSUSE:Factory/.telemetrygen.new.1966 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "telemetrygen" Tue May 12 19:27:42 2026 rev:14 rq:1352609 version:0.152.0 Changes: -------- --- /work/SRC/openSUSE:Factory/telemetrygen/telemetrygen.changes 2026-04-30 20:31:29.689495963 +0200 +++ /work/SRC/openSUSE:Factory/.telemetrygen.new.1966/telemetrygen.changes 2026-05-12 19:29:59.043332388 +0200 @@ -1,0 +2,62 @@ +Tue May 12 05:24:15 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 0.152.0: + * No telemetrygen-related changes + * Dependencies + - [chore] Update core dependencies (#48261) + - [chore][govuln] Update golang.org/x/net to v0.53.0 to fix + GO-2026-4918 (#48224) + - Update module github.com/prometheus/prometheus to v0.311.3 + (#47949) + - Update module github.com/apache/thrift to v0.23.0 [SECURITY] + - abandoned (#48179) + - Bump github.com/apache/thrift from 0.22.0 to 0.23.0 in + /receiver/zipkinreceiver (#48177) + - [chore] [receiver/postgresqlreceiver] update lib-pq from + v1.10.9 to v1.12.3 (#47162) + - Update module google.golang.org/api to v0.278.0 (#48162) + - Update redis Docker tag to v8.6.3 (#48158) + - Update module github.com/cockroachdb/pebble/v2 to v2.1.5 + (#48152) + - Update module gitlab.com/gitlab-org/api/client-go/v2 to + v2.24.1 (#48153) + - Update module google.golang.org/api to v0.277.0 (#48147) + - Update module github.com/go-sql-driver/mysql to v1.10.0 + (#48138) + - Update module gitlab.com/gitlab-org/api/client-go/v2 to + v2.24.0 (#48141) + - Update module github.com/fsnotify/fsnotify to v1.10.1 - + abandoned (#48135) + - Update module google.golang.org/grpc to v1.81.0 (#48142) + - Update module github.com/ClickHouse/clickhouse-go/v2 to + v2.46.0 (#48134) + - Update module github.com/Masterminds/semver/v3 to v3.5.0 + (#48139) + - Update module github.com/buger/jsonparser to v1.2.0 (#48131) + - Update docker-compose deps to v0.151.0 (#48130) + - Update module go.opentelemetry.io/ebpf-profiler to + v0.0.202618 (#48124) + - Update module + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common + to v1.3.90 (#48122) + - Update module github.com/twmb/franz-go to v1.21.1 (#48123) + - Update module github.com/shirou/gopsutil/v4 to v4.26.4 + (#48121) + - Update module github.com/DataDog/agent-payload/v5 to v5.0.195 + (#48116) + - Update module github.com/klauspost/compress to v1.18.6 + (#48117) + - Update module github.com/SAP/go-hdb to v1.16.7 (#48120) + - Update module github.com/getsentry/sentry-go to v0.46.2 + (#48119) + - Update All github.com/aws packages (#48114) + - Update github-actions deps (#48115) + - [chore] Update core dependencies (#48069) + - Update module go.uber.org/zap to v1.28.0 (#47997) + - [chore][exporter/kafka] Bump franz-go from v1.20.7 to + v1.21.0, kfake to v0.0.0-20260421215025 (#48004) + - Update module + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common + to v1.3.89 (#48001) + +------------------------------------------------------------------- Old: ---- telemetrygen-0.151.0.obscpio New: ---- telemetrygen-0.152.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ telemetrygen.spec ++++++ --- /var/tmp/diff_new_pack.6DMXir/_old 2026-05-12 19:30:00.679400195 +0200 +++ /var/tmp/diff_new_pack.6DMXir/_new 2026-05-12 19:30:00.679400195 +0200 @@ -17,7 +17,7 @@ Name: telemetrygen -Version: 0.151.0 +Version: 0.152.0 Release: 0 Summary: Telemetry generator for OpenTelemetry License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.6DMXir/_old 2026-05-12 19:30:00.723402018 +0200 +++ /var/tmp/diff_new_pack.6DMXir/_new 2026-05-12 19:30:00.727402185 +0200 @@ -2,7 +2,7 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/open-telemetry/opentelemetry-collector-contrib.git</param> <param name="scm">git</param> - <param name="revision">refs/tags/v0.151.0</param> + <param name="revision">refs/tags/v0.152.0</param> <param name="match-tag">v*</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.6DMXir/_old 2026-05-12 19:30:00.763403677 +0200 +++ /var/tmp/diff_new_pack.6DMXir/_new 2026-05-12 19:30:00.767403842 +0200 @@ -3,6 +3,6 @@ <param name="url">https://github.com/open-telemetry/opentelemetry-collector-contrib</param> <param name="changesrevision">da05052499099b69cbb68a679a0efeac95a5d88c</param></service><service name="tar_scm"> <param name="url">https://github.com/open-telemetry/opentelemetry-collector-contrib.git</param> - <param name="changesrevision">25a1fd0fc4bafc64fc28ab33516bedf30b3c9a50</param></service></servicedata> + <param name="changesrevision">77b71af08aecde89bb0e10d66c7863ac4a1c31a6</param></service></servicedata> (No newline at EOF) ++++++ telemetrygen-0.151.0.obscpio -> telemetrygen-0.152.0.obscpio ++++++ ++++ 122427 lines of diff (skipped) ++++++ telemetrygen.obsinfo ++++++ --- /var/tmp/diff_new_pack.6DMXir/_old 2026-05-12 19:30:14.759983760 +0200 +++ /var/tmp/diff_new_pack.6DMXir/_new 2026-05-12 19:30:14.767984091 +0200 @@ -1,5 +1,5 @@ name: telemetrygen -version: 0.151.0 -mtime: 1777413063 -commit: 25a1fd0fc4bafc64fc28ab33516bedf30b3c9a50 +version: 0.152.0 +mtime: 1778504669 +commit: 77b71af08aecde89bb0e10d66c7863ac4a1c31a6 ++++++ vendor.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/go.opentelemetry.io/collector/pdata/pcommon/value.go new/vendor/go.opentelemetry.io/collector/pdata/pcommon/value.go --- old/vendor/go.opentelemetry.io/collector/pdata/pcommon/value.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/go.opentelemetry.io/collector/pdata/pcommon/value.go 2026-05-11 15:04:29.000000000 +0200 @@ -4,11 +4,13 @@ package pcommon // import "go.opentelemetry.io/collector/pdata/pcommon" import ( + "bytes" "encoding/base64" "encoding/json" "fmt" "math" "strconv" + "strings" "go.opentelemetry.io/collector/pdata/internal" ) @@ -401,21 +403,36 @@ return strconv.FormatInt(v.Int(), 10) case ValueTypeMap: - jsonStr, _ := json.Marshal(v.Map().AsRaw()) - return string(jsonStr) + return marshalJSONNoHTMLEscape(v.Map().AsRaw()) case ValueTypeBytes: return base64.StdEncoding.EncodeToString(*v.Bytes().getOrig()) case ValueTypeSlice: - jsonStr, _ := json.Marshal(v.Slice().AsRaw()) - return string(jsonStr) + return marshalJSONNoHTMLEscape(v.Slice().AsRaw()) default: return fmt.Sprintf("<Unknown OpenTelemetry attribute value type %q>", v.Type()) } } +// marshalJSONNoHTMLEscape marshals v as JSON without HTML-escaping "<", ">", +// and "&". This matches the behavior of AsString for ValueTypeStr (which +// returns the raw string) and keeps structured values (maps, slices) free +// of escape sequences like "\u003c" that are only meaningful in HTML contexts. +func marshalJSONNoHTMLEscape(v any) string { + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + enc.SetEscapeHTML(false) + // Encode cannot fail for the map/slice values produced by AsRaw(), which + // only contain primitive types, so the error is intentionally ignored — + // consistent with the json.Marshal calls it replaces. + _ = enc.Encode(v) + // json.Encoder.Encode always appends a trailing newline; strip it so the + // output matches json.Marshal. + return strings.TrimRight(buf.String(), "\n") +} + // See https://cs.opensource.google/go/go/+/refs/tags/go1.17.7:src/encoding/json/encode.go;l=585. // This allows us to avoid using reflection. func float64AsString(f float64) string { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/go.uber.org/zap/CHANGELOG.md new/vendor/go.uber.org/zap/CHANGELOG.md --- old/vendor/go.uber.org/zap/CHANGELOG.md 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/go.uber.org/zap/CHANGELOG.md 2026-05-11 15:04:29.000000000 +0200 @@ -3,6 +3,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.28.0 (27 Apr 2026) +Enhancements: +* [#1534][]: Add `zapcore.CheckPreWriteHook` and `CheckedEntry.Before` method for transforming entries before they are written to any Cores. + ## 1.27.1 (19 Nov 2025) Enhancements: * [#1501][]: prevent `Object` from panicking on nils diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/go.uber.org/zap/zapcore/entry.go new/vendor/go.uber.org/zap/zapcore/entry.go --- old/vendor/go.uber.org/zap/zapcore/entry.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/go.uber.org/zap/zapcore/entry.go 2026-05-11 15:04:29.000000000 +0200 @@ -201,6 +201,14 @@ var _ CheckWriteHook = CheckWriteAction(0) +// CheckPreWriteHook is a function that transforms an Entry and its Fields +// before they are written to cores. Register one on a CheckedEntry with the +// Before method. +// +// Pre-write hooks run in the order they were added, before any Core's Write +// method is called. They may modify the Entry and Fields freely. +type CheckPreWriteHook func(Entry, []Field) (Entry, []Field) + // CheckedEntry is an Entry together with a collection of Cores that have // already agreed to log it. // @@ -213,6 +221,7 @@ dirty bool // best-effort detection of pool misuse after CheckWriteHook cores []Core + before []CheckPreWriteHook } func (ce *CheckedEntry) reset() { @@ -225,6 +234,10 @@ ce.cores[i] = nil } ce.cores = ce.cores[:0] + for i := range ce.before { + ce.before[i] = nil + } + ce.before = ce.before[:0] } // Write writes the entry to the stored Cores, returns any errors, and returns @@ -253,9 +266,14 @@ } ce.dirty = true + ent := ce.Entry + for i := range ce.before { + ent, fields = ce.before[i](ent, fields) + } + var err error for i := range ce.cores { - err = multierr.Append(err, ce.cores[i].Write(ce.Entry, fields)) + err = multierr.Append(err, ce.cores[i].Write(ent, fields)) } if err != nil && ce.ErrorOutput != nil { _, _ = fmt.Fprintf( @@ -295,6 +313,18 @@ return ce.After(ent, should) } +// Before adds a pre-write hook that transforms the Entry and Fields before +// they are written to any registered Cores. Multiple hooks run in the order +// they were added. It's safe to call this on nil CheckedEntry references. +func (ce *CheckedEntry) Before(ent Entry, hook CheckPreWriteHook) *CheckedEntry { + if ce == nil { + ce = getCheckedEntry() + ce.Entry = ent + } + ce.before = append(ce.before, hook) + return ce +} + // After sets this CheckEntry's CheckWriteHook, which will be called after this // log entry has been written. It's safe to call this on nil CheckedEntry // references. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/net/http2/hpack/tables.go new/vendor/golang.org/x/net/http2/hpack/tables.go --- old/vendor/golang.org/x/net/http2/hpack/tables.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/golang.org/x/net/http2/hpack/tables.go 2026-05-11 15:04:29.000000000 +0200 @@ -6,6 +6,7 @@ import ( "fmt" + "strings" ) // headerFieldTable implements a list of HeaderFields. @@ -54,10 +55,16 @@ // addEntry adds a new entry. func (t *headerFieldTable) addEntry(f HeaderField) { + // Prevent f from escaping to the heap. + f2 := HeaderField{ + Name: strings.Clone(f.Name), + Value: strings.Clone(f.Value), + Sensitive: f.Sensitive, + } id := uint64(t.len()) + t.evictCount + 1 - t.byName[f.Name] = id - t.byNameValue[pairNameValue{f.Name, f.Value}] = id - t.ents = append(t.ents, f) + t.byName[f2.Name] = id + t.byNameValue[pairNameValue{f2.Name, f2.Value}] = id + t.ents = append(t.ents, f2) } // evictOldest evicts the n oldest entries in the table. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/net/http2/transport.go new/vendor/golang.org/x/net/http2/transport.go --- old/vendor/golang.org/x/net/http2/transport.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/golang.org/x/net/http2/transport.go 2026-05-11 15:04:29.000000000 +0200 @@ -718,9 +718,6 @@ } func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { - if t.transportTestHooks != nil { - return t.newClientConn(nil, singleUse, nil) - } host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -2861,6 +2858,9 @@ var seenMaxConcurrentStreams bool err := f.ForeachSetting(func(s Setting) error { + if err := s.Valid(); err != nil { + return err + } switch s.ID { case SettingMaxFrameSize: cc.maxFrameSize = s.Val @@ -2892,9 +2892,6 @@ cc.henc.SetMaxDynamicTableSize(s.Val) cc.peerMaxHeaderTableSize = s.Val case SettingEnableConnectProtocol: - if err := s.Valid(); err != nil { - return err - } // If the peer wants to send us SETTINGS_ENABLE_CONNECT_PROTOCOL, // we require that it do so in the first SETTINGS frame. // diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/sys/windows/dll_windows.go new/vendor/golang.org/x/sys/windows/dll_windows.go --- old/vendor/golang.org/x/sys/windows/dll_windows.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/golang.org/x/sys/windows/dll_windows.go 2026-05-11 15:04:29.000000000 +0200 @@ -163,42 +163,7 @@ // (according to the semantics of the specific function being called) before consulting // the error. The error will be guaranteed to contain windows.Errno. func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { - switch len(a) { - case 0: - return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0) - case 1: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0) - case 2: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0) - case 3: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2]) - case 4: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0) - case 5: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0) - case 6: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5]) - case 7: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) - case 8: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) - case 9: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) - case 10: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) - case 11: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) - case 12: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) - case 13: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) - case 14: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) - case 15: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) - default: - panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".") - } + return syscall.SyscallN(p.Addr(), a...) } // A LazyDLL implements access to a single DLL. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/golang.org/x/sys/windows/security_windows.go new/vendor/golang.org/x/sys/windows/security_windows.go --- old/vendor/golang.org/x/sys/windows/security_windows.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/golang.org/x/sys/windows/security_windows.go 2026-05-11 15:04:29.000000000 +0200 @@ -1438,13 +1438,17 @@ } // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security -// descriptor result on the Go heap. +// descriptor result on the Go heap. The security descriptor might be nil, even when err is nil, if the object exists +// but has no security descriptor. func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) { var winHeapSD *SECURITY_DESCRIPTOR err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD) if err != nil { return } + if winHeapSD == nil { + return nil, nil + } defer LocalFree(Handle(unsafe.Pointer(winHeapSD))) return winHeapSD.copySelfRelativeSecurityDescriptor(), nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/clientconn.go new/vendor/google.golang.org/grpc/clientconn.go --- old/vendor/google.golang.org/grpc/clientconn.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/clientconn.go 2026-05-11 15:04:29.000000000 +0200 @@ -24,10 +24,12 @@ "fmt" "math" "net/url" + "os" "slices" "strings" "sync" "sync/atomic" + "syscall" "time" "google.golang.org/grpc/balancer" @@ -1268,8 +1270,9 @@ channelz *channelz.SubChannel - localityLabel string - backendServiceLabel string + localityLabel string + backendServiceLabel string + disconnectErrorLabel string } // Note: this requires a lock on ac.mu. @@ -1286,9 +1289,14 @@ // TODO: https://github.com/grpc/grpc-go/issues/7862 - Remove the second // part of the if condition below once the issue is fixed. if ac.state == connectivity.Ready || (ac.state == connectivity.Connecting && s == connectivity.Idle) { - disconnectionsMetric.Record(ac.cc.metricsRecorderList, 1, ac.cc.target, ac.backendServiceLabel, ac.localityLabel, "unknown") + disconnectError := ac.disconnectErrorLabel + if disconnectError == "" { + disconnectError = "unknown" + } + disconnectionsMetric.Record(ac.cc.metricsRecorderList, 1, ac.cc.target, ac.backendServiceLabel, ac.localityLabel, disconnectError) openConnectionsMetric.Record(ac.cc.metricsRecorderList, -1, ac.cc.target, ac.backendServiceLabel, ac.securityLevelLocked(), ac.localityLabel) } + ac.disconnectErrorLabel = "" // Reset for next time ac.state = s ac.channelz.ChannelMetrics.State.Store(&s) if lastErr == nil { @@ -1483,11 +1491,11 @@ addr.ServerName = ac.cc.getServerName(addr) hctx, hcancel := context.WithCancel(ctx) - onClose := func(r transport.GoAwayReason) { + onClose := func(info transport.GoAwayInfo) { ac.mu.Lock() defer ac.mu.Unlock() // adjust params based on GoAwayReason - ac.adjustParams(r) + ac.adjustParams(info.Reason) if ctx.Err() != nil { // Already shut down or connection attempt canceled. tearDown() or // updateAddrs() already cleared the transport and canceled hctx @@ -1504,6 +1512,7 @@ return } ac.transport = nil + ac.disconnectErrorLabel = disconnectErrorString(info) // Refresh the name resolver on any connection loss. ac.cc.resolveNow(resolver.ResolveNowOptions{}) // Always go idle and wait for the LB policy to initiate a new @@ -1560,6 +1569,32 @@ return nil } +// disconnectErrorString returns the grpc.disconnect_error metric label corresponding +// to the provided transport.GoAwayInfo, as specified by gRFC A94: +// https://github.com/grpc/proposal/blob/master/A94-grpc-subchannel-disconnections-metrics.md +func disconnectErrorString(info transport.GoAwayInfo) string { + err := info.Err + var sysErr syscall.Errno + switch { + case info.Reason != transport.GoAwayInvalid: + return fmt.Sprintf("GOAWAY %s", info.GoAwayCode.String()) + case err == nil: + return "unknown" + case errors.Is(err, context.Canceled): + return "subchannel shutdown" + case errors.Is(err, syscall.ECONNRESET): + return "connection reset" + case errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, context.DeadlineExceeded), errors.Is(err, os.ErrDeadlineExceeded): + return "connection timed out" + case errors.Is(err, syscall.ECONNABORTED): + return "connection aborted" + case errors.As(err, &sysErr): + return "socket error" + default: + return "unknown" + } +} + // startHealthCheck starts the health checking stream (RPC) to watch the health // stats of this connection if health checking is requested and configured. // @@ -1663,6 +1698,9 @@ } curTr := ac.transport ac.transport = nil + if ac.disconnectErrorLabel == "" { + ac.disconnectErrorLabel = "subchannel shutdown" + } // We have to set the state to Shutdown before anything else to prevent races // between setting the state and logic that waits on context cancellation / etc. ac.updateConnectivityState(connectivity.Shutdown, nil) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/experimental/stats/metrics.go new/vendor/google.golang.org/grpc/experimental/stats/metrics.go --- old/vendor/google.golang.org/grpc/experimental/stats/metrics.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/experimental/stats/metrics.go 2026-05-11 15:04:29.000000000 +0200 @@ -20,10 +20,27 @@ package stats import ( + "context" + "google.golang.org/grpc/internal" "google.golang.org/grpc/stats" ) +type customLabelKey struct{} + +// NewContextWithCustomLabel returns a new context with the provided custom label +// attached. The label will be propagated to all metric instruments specified in gRFC A108. +func NewContextWithCustomLabel(ctx context.Context, label string) context.Context { + return context.WithValue(ctx, customLabelKey{}, label) +} + +// CustomLabelFromContext returns the custom label from the context if it exists. +// If the custom label is not present, it returns an empty string. +func CustomLabelFromContext(ctx context.Context) string { + label, _ := ctx.Value(customLabelKey{}).(string) + return label +} + // MetricsRecorder records on metrics derived from metric registry. // Implementors must embed UnimplementedMetricsRecorder. type MetricsRecorder interface { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go new/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go --- old/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go 2026-05-11 15:04:29.000000000 +0200 @@ -126,6 +126,16 @@ // enabled by setting the env variable // GRPC_EXPERIMENTAL_ENABLE_PRIORITY_LB_CHILD_POLICY_CACHE to true. EnablePriorityLBChildPolicyCache = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_PRIORITY_LB_CHILD_POLICY_CACHE", false) + + // EnableHTTPFramerReadBufferPooling enables the use of the + // readyreader.Reader interface to perform non-memory-pinning reads, + // provided the underlying net.Conn supports it. This reduces memory usage + // when subchannels are idle. + // + // This environment variable serves as an escape hatch to disable the + // feature if unforeseen issues arise, and it will be removed in a future + // release. + EnableHTTPFramerReadBufferPooling = boolFromEnv("GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING", true) ) func boolFromEnv(envVar string, def bool) bool { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/envconfig/xds.go new/vendor/google.golang.org/grpc/internal/envconfig/xds.go --- old/vendor/google.golang.org/grpc/internal/envconfig/xds.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/envconfig/xds.go 2026-05-11 15:04:29.000000000 +0200 @@ -79,4 +79,14 @@ // xDS bootstrap configuration via the `call_creds` field. For more details, // see: https://github.com/grpc/proposal/blob/master/A97-xds-jwt-call-creds.md XDSBootstrapCallCredsEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_BOOTSTRAP_CALL_CREDS", false) + + // XDSSNIEnabled controls if gRPC should send SNI information in xDS + // configured TLS handshakes. For more details, see: + // https://github.com/grpc/proposal/blob/master/A101-SNI-setting-and-SNI-SAN-validation.md + XDSSNIEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_SNI", false) + + // XDSORCAToLRSPropEnabled controls whether ORCA metrics are explicitly + // filtered and prefix-propagated to the LRS server. For more details, see: + // https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md + XDSORCAToLRSPropEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION", false) ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go new/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go --- old/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/mem/buffer_pool.go 2026-05-11 15:04:29.000000000 +0200 @@ -73,7 +73,7 @@ func NewBinaryTieredBufferPool(powerOfTwoExponents ...uint8) (*BinaryTieredBufferPool, error) { return newBinaryTiered(func(size int) bufferPool { return newSizedBufferPool(size, true) - }, &simpleBufferPool{shouldZero: true}, powerOfTwoExponents...) + }, &SimpleBufferPool{shouldZero: true}, powerOfTwoExponents...) } // NewDirtyBinaryTieredBufferPool returns a BufferPool backed by multiple @@ -82,7 +82,7 @@ func NewDirtyBinaryTieredBufferPool(powerOfTwoExponents ...uint8) (*BinaryTieredBufferPool, error) { return newBinaryTiered(func(size int) bufferPool { return newSizedBufferPool(size, false) - }, &simpleBufferPool{shouldZero: false}, powerOfTwoExponents...) + }, NewDirtySimplePool(), powerOfTwoExponents...) } func newBinaryTiered(sizedPoolFactory func(int) bufferPool, fallbackPool bufferPool, powerOfTwoExponents ...uint8) (*BinaryTieredBufferPool, error) { @@ -258,7 +258,7 @@ // buffer pools for different sizes of buffers. type TieredBufferPool struct { sizedPools []*sizedBufferPool - fallbackPool simpleBufferPool + fallbackPool SimpleBufferPool } // NewTieredBufferPool returns a BufferPool implementation that uses multiple @@ -271,7 +271,7 @@ } return &TieredBufferPool{ sizedPools: pools, - fallbackPool: simpleBufferPool{shouldZero: true}, + fallbackPool: SimpleBufferPool{shouldZero: true}, } } @@ -297,16 +297,26 @@ return p.sizedPools[poolIdx] } -// simpleBufferPool is an implementation of the BufferPool interface that +// SimpleBufferPool is an implementation of the mem.BufferPool interface that // attempts to pool buffers with a sync.Pool. When Get is invoked, it tries to // acquire a buffer from the pool but if that buffer is too small, it returns it // to the pool and creates a new one. -type simpleBufferPool struct { +type SimpleBufferPool struct { pool sync.Pool shouldZero bool } -func (p *simpleBufferPool) Get(size int) *[]byte { +// NewDirtySimplePool constructs a [SimpleBufferPool]. It does not initialize +// the buffers before returning them. Callers must ensure they don't read the +// buffers before writing data to them. +func NewDirtySimplePool() *SimpleBufferPool { + return &SimpleBufferPool{ + shouldZero: false, + } +} + +// Get returns a buffer with specified length from the pool. +func (p *SimpleBufferPool) Get(size int) *[]byte { bs, ok := p.pool.Get().(*[]byte) if ok && cap(*bs) >= size { if p.shouldZero { @@ -333,6 +343,7 @@ return &b } -func (p *simpleBufferPool) Put(buf *[]byte) { +// Put returns a buffer to the pool. +func (p *SimpleBufferPool) Put(buf *[]byte) { p.pool.Put(buf) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/resolver/config_selector.go new/vendor/google.golang.org/grpc/internal/resolver/config_selector.go --- old/vendor/google.golang.org/grpc/internal/resolver/config_selector.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/resolver/config_selector.go 2026-05-11 15:04:29.000000000 +0200 @@ -115,6 +115,9 @@ // ClientStream after done is called, since the interceptor is invoked by // application-layer operations. done must never be nil when called. NewStream(ctx context.Context, ri RPCInfo, done func(), newStream func(ctx context.Context, done func()) (ClientStream, error)) (ClientStream, error) + // Close closes the interceptor. Once called, no new calls to NewStream are + // accepted. Ongoing calls to NewStream are allowed to complete. + Close() } // ServerInterceptor is an interceptor for incoming RPC's on gRPC server side. @@ -123,6 +126,9 @@ // information about connection RPC was received on, and HTTP Headers. This // information will be piped into context. AllowRPC(ctx context.Context) error // TODO: Make this a real interceptor for filters such as rate limiting. + // Close closes the interceptor. Once called, no new calls to NewStream are + // accepted. Ongoing calls to NewStream are allowed to complete. + Close() } type csKeyType string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/transport/http2_client.go new/vendor/google.golang.org/grpc/internal/transport/http2_client.go --- old/vendor/google.golang.org/grpc/internal/transport/http2_client.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/transport/http2_client.go 2026-05-11 15:04:29.000000000 +0200 @@ -134,6 +134,8 @@ // goAwayDebugMessage contains a detailed human readable string about a // GoAway frame, useful for error messages. goAwayDebugMessage string + // goAwayCode records the http2.ErrCode received with the GoAway frame. + goAwayCode http2.ErrCode // A condition variable used to signal when the keepalive goroutine should // go dormant. The condition for dormancy is based on the number of active // streams and the `PermitWithoutStream` keepalive client parameter. And @@ -147,7 +149,7 @@ channelz *channelz.Socket - onClose func(GoAwayReason) + onClose OnCloseFunc bufferPool mem.BufferPool @@ -204,7 +206,7 @@ // NewHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose func(GoAwayReason)) (_ ClientTransport, err error) { +func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose OnCloseFunc) (_ ClientTransport, err error) { scheme := "http" ctx, cancel := context.WithCancel(ctx) defer func() { @@ -1015,7 +1017,7 @@ // Call t.onClose ASAP to prevent the client from attempting to create new // streams. if t.state != draining { - t.onClose(GoAwayInvalid) + t.onClose(GoAwayInfo{Reason: GoAwayInvalid, GoAwayCode: http2.ErrCodeNo, Err: err}) } t.state = closing streams := t.activeStreams @@ -1086,7 +1088,7 @@ if t.logger.V(logLevel) { t.logger.Infof("GracefulClose called") } - t.onClose(GoAwayInvalid) + t.onClose(GoAwayInfo{Reason: GoAwayInvalid, GoAwayCode: http2.ErrCodeNo}) t.state = draining active := len(t.activeStreams) t.mu.Unlock() @@ -1236,7 +1238,10 @@ // The server has closed the stream without sending trailers. Record that // the read direction is closed, and set the status appropriately. if f.StreamEnded() { - t.closeStream(s, io.EOF, false, http2.ErrCodeNo, status.New(codes.Internal, "server closed the stream without sending trailers"), nil, true) + // If client received END_STREAM from server while stream was still + // active, send RST_STREAM. + rstStream := s.getState() == streamActive + t.closeStream(s, io.EOF, rstStream, http2.ErrCodeNo, status.New(codes.Internal, "server closed the stream without sending trailers"), nil, true) } } @@ -1372,7 +1377,7 @@ // draining, to allow the client to stop attempting to create streams // before disallowing new streams on this connection. if t.state != draining { - t.onClose(t.goAwayReason) + t.onClose(GoAwayInfo{Reason: t.goAwayReason, GoAwayCode: t.goAwayCode}) t.state = draining } } @@ -1422,6 +1427,7 @@ } else { t.goAwayDebugMessage = fmt.Sprintf("code: %s, debug data: %q", f.ErrCode, string(f.DebugData())) } + t.goAwayCode = f.ErrCode } func (t *http2Client) GetGoAwayReason() (GoAwayReason, string) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/transport/http_util.go new/vendor/google.golang.org/grpc/internal/transport/http_util.go --- old/vendor/google.golang.org/grpc/internal/transport/http_util.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/transport/http_util.go 2026-05-11 15:04:29.000000000 +0200 @@ -36,6 +36,9 @@ "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" "google.golang.org/grpc/codes" + "google.golang.org/grpc/internal/envconfig" + imem "google.golang.org/grpc/internal/mem" + "google.golang.org/grpc/internal/transport/readyreader" "google.golang.org/grpc/mem" ) @@ -296,7 +299,7 @@ } type bufWriter struct { - pool *sync.Pool + pool *imem.SimpleBufferPool buf []byte offset int batchSize int @@ -304,7 +307,7 @@ err error } -func newBufWriter(conn io.Writer, batchSize int, pool *sync.Pool) *bufWriter { +func newBufWriter(conn io.Writer, batchSize int, pool *imem.SimpleBufferPool) *bufWriter { w := &bufWriter{ batchSize: batchSize, conn: conn, @@ -326,7 +329,7 @@ return n, toIOError(err) } if w.buf == nil { - b := w.pool.Get().(*[]byte) + b := w.pool.Get(w.batchSize) w.buf = *b } written := 0 @@ -407,22 +410,32 @@ errDetail error } -var writeBufferPoolMap = make(map[int]*sync.Pool) -var writeBufferMutex sync.Mutex +var ioBufferPoolMap = make(map[int]*imem.SimpleBufferPool) +var ioBufferMutex sync.Mutex + +func bufferedReader(r io.Reader, bufSize int) io.Reader { + if bufSize <= 0 { + return r + } + if envconfig.EnableHTTPFramerReadBufferPooling { + if rr := readyreader.NewNonBlocking(r); rr != nil { + readPool := ioBufferPool(bufSize) + return readyreader.NewBuffered(rr, bufSize, readPool) + } + } + return bufio.NewReaderSize(r, bufSize) +} func newFramer(conn io.ReadWriter, writeBufferSize, readBufferSize int, sharedWriteBuffer bool, maxHeaderListSize uint32, memPool mem.BufferPool) *framer { if writeBufferSize < 0 { writeBufferSize = 0 } - var r io.Reader = conn - if readBufferSize > 0 { - r = bufio.NewReaderSize(r, readBufferSize) - } - var pool *sync.Pool + r := bufferedReader(conn, readBufferSize) + var writePool *imem.SimpleBufferPool if sharedWriteBuffer { - pool = getWriteBufferPool(writeBufferSize) + writePool = ioBufferPool(writeBufferSize) } - w := newBufWriter(conn, writeBufferSize, pool) + w := newBufWriter(conn, writeBufferSize, writePool) f := &framer{ writer: w, fr: http2.NewFramer(w, r), @@ -578,20 +591,15 @@ return df.FrameHeader } -func getWriteBufferPool(size int) *sync.Pool { - writeBufferMutex.Lock() - defer writeBufferMutex.Unlock() - pool, ok := writeBufferPoolMap[size] +func ioBufferPool(size int) *imem.SimpleBufferPool { + ioBufferMutex.Lock() + defer ioBufferMutex.Unlock() + pool, ok := ioBufferPoolMap[size] if ok { return pool } - pool = &sync.Pool{ - New: func() any { - b := make([]byte, size) - return &b - }, - } - writeBufferPoolMap[size] = pool + pool = imem.NewDirtySimplePool() + ioBufferPoolMap[size] = pool return pool } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go new/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go --- old/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_linux.go 2026-05-11 15:04:29.000000000 +0200 @@ -0,0 +1,39 @@ +/* + * + * Copyright 2026 gRPC 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package readyreader + +import "syscall" + +func isRawConnSupported() bool { + return true +} + +// sysRead uses the standard syscall package rather than the modern unix package +// to avoid triggering the race detector. Because both packages perform sync +// operations on a local variable to satisfy the race detector, mixing them +// for read and write syscalls causes data races. We use syscall here to remain +// consistent with net.Conn implementations in standard library. +func sysRead(fd uintptr, p []byte) (int, error) { + return syscall.Read(int(fd), p) +} + +// wouldBlock checks standard Unix non-blocking errors. +func wouldBlock(err error) bool { + return err == syscall.EAGAIN || err == syscall.EWOULDBLOCK +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go new/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go --- old/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/google.golang.org/grpc/internal/transport/readyreader/raw_conn_nonlinux.go 2026-05-11 15:04:29.000000000 +0200 @@ -0,0 +1,35 @@ +//go:build !linux + +/* + * + * Copyright 2026 gRPC 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package readyreader + +func isRawConnSupported() bool { + return false +} + +// sysRead is not implemented. Support can be added in the future if necessary. +func sysRead(uintptr, []byte) (int, error) { + panic("RawConn functionality is not implemented for non-unix platforms.") +} + +// wouldBlock is not implemented. Support can be added in the future if necessary. +func wouldBlock(error) bool { + panic("RawConn functionality is not implemented for non-unix platforms.") +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go new/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go --- old/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/google.golang.org/grpc/internal/transport/readyreader/ready_reader.go 2026-05-11 15:04:29.000000000 +0200 @@ -0,0 +1,253 @@ +/* + * + * Copyright 2026 gRPC 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package readyreader provides utilities to perform non-memory-pinning reads. +package readyreader + +import ( + "io" + "net" + "syscall" + + "google.golang.org/grpc/mem" +) + +// Reader is an optional interface that can be implemented by [net.Conn] +// implementations to enable gRPC to perform non-memory-pinning reads. +type Reader interface { + // ReadOnReady waits for data to arrive, fetches a buffer, and performs a + // read. When the underlying IO is readable, it allocates a buffer of size + // bufSize from the pool and reads up to bufSize bytes into the buffer. + // + // It returns a pointer to the buffer so it can be returned to the pool + // later, the number of bytes read, and an error. + // + // Callers should always process the n > 0 bytes returned before considering + // the error. Doing so correctly handles I/O errors that happen after + // reading some bytes, as well as both of the allowed EOF behaviors. + ReadOnReady(bufSize int, pool mem.BufferPool) (b *[]byte, n int, err error) +} + +// nonBlockingReader is optimized for non-memory-pinning reads using the RawConn +// interface. +type nonBlockingReader struct { + raw syscall.RawConn + // The following fields are stored as field to avoid heap allocations. + state readState + doRead func(fd uintptr) bool +} + +type readState struct { + // Request params. + bufSize int + pool mem.BufferPool + + // Response params. + readError error + bytesRead int + buf *[]byte +} + +// NewNonBlocking returns a ReadyReader if the passed reader supports +// non-memory-pinning reads, else nil. +func NewNonBlocking(r io.Reader) Reader { + if rr, ok := r.(Reader); ok { + return rr + } + if !isRawConnSupported() { + return nil + } + // We restrict the types before asserting syscall.Conn. The credentials + // package may return a wrapper that implements syscall.Conn by embedding + // both the raw connection and the encrypted connection. If the code + // attempts to read directly from the raw syscall.RawConn, it would read + // encrypted data. + switch r.(type) { + case *net.TCPConn, *net.UDPConn, *net.UnixConn, *net.IPConn: + default: + return nil + } + sysConn, ok := r.(syscall.Conn) + if !ok { + return nil + } + raw, err := sysConn.SyscallConn() + if err != nil { + return nil + } + rr := &nonBlockingReader{raw: raw} + rr.doRead = func(fd uintptr) bool { + s := &rr.state + + s.buf = s.pool.Get(s.bufSize) + s.bytesRead, s.readError = sysRead(fd, *s.buf) + + if s.readError != nil { + s.pool.Put(s.buf) + s.buf = nil + } + return !wouldBlock(s.readError) + } + return rr +} + +func (c *nonBlockingReader) ReadOnReady(bufSize int, pool mem.BufferPool) (*[]byte, int, error) { + c.state = readState{ + pool: pool, + bufSize: bufSize, + } + err := c.raw.Read(c.doRead) + + buf := c.state.buf + n := c.state.bytesRead + readErr := c.state.readError + c.state = readState{} + + if err != nil { + if buf != nil { + pool.Put(buf) + } + return nil, 0, err + } + if readErr != nil { + // buffer is already released in the callback. + return nil, 0, readErr + } + if n == 0 { + // syscall.Read doesn't consider a graceful socket closure to be an + // error condition, but Go's io.Reader expects an EOF error. + pool.Put(buf) + return nil, 0, io.EOF + } + return buf, n, nil +} + +type blockingReader struct { + reader io.Reader +} + +func (c *blockingReader) ReadOnReady(bufSize int, pool mem.BufferPool) (*[]byte, int, error) { + buf := pool.Get(bufSize) + n, err := c.reader.Read(*buf) + if err != nil { + pool.Put(buf) + return nil, 0, err + } + return buf, n, nil +} + +// New detects if [syscall.RawConn] is available for non-memory-pinning reads. +// If [syscall.RawConn] is unavailable, it falls back to using the simpler +// [io.Reader] interface for reads. +func New(r io.Reader) Reader { + if r := NewNonBlocking(r); r != nil { + return r + } + return &blockingReader{reader: r} +} + +// bufReadyReader implements buffering for a ReadyReader object. +// A new bufReadyReader is created by calling [NewBuffered]. +type bufReadyReader struct { + buf *[]byte + pool mem.BufferPool + bufSize int + rd Reader // reader provided by the caller + r, w int // buf read and write positions + err error + constPool constBufferPool // stored as a field to avoid heap allocations. +} + +// NewBuffered returns a new [io.Reader] with a buffer of the specified size +// which is allocated from the provided pool. +func NewBuffered(rd Reader, size int, pool mem.BufferPool) io.Reader { + return &bufReadyReader{ + rd: rd, + pool: pool, + bufSize: size, + } +} + +func (b *bufReadyReader) readErr() error { + err := b.err + b.err = nil + return err +} + +func (b *bufReadyReader) buffered() int { return b.w - b.r } + +// Read reads data into p. It returns the number of bytes read into p. The +// bytes are taken from at most one Read on the underlying [ReadyReader], +// hence n may be less than len(p). If the underlying [ReadyReader] can return +// a non-zero count with io.EOF, then this Read method can do so as well; see +// the [io.Reader] docs. +func (b *bufReadyReader) Read(p []byte) (n int, err error) { + n = len(p) + if n == 0 { + if b.buffered() > 0 { + return 0, nil + } + return 0, b.readErr() + } + if b.r == b.w { + if b.err != nil { + return 0, b.readErr() + } + if len(p) >= b.bufSize { + // Large read, empty buffer. + // Read directly into p to avoid copy. + b.constPool.buffer = p + _, n, b.err = b.rd.ReadOnReady(len(p), &b.constPool) + return n, b.readErr() + } + // One read. + b.r = 0 + b.w = 0 + b.buf, n, b.err = b.rd.ReadOnReady(b.bufSize, b.pool) + if n == 0 { + if b.buf != nil { + b.pool.Put(b.buf) + b.buf = nil + } + return 0, b.readErr() + } + b.w += n + } + + // copy as much as we can + // b.buf must be non-nil since b.r != b.w. + buf := *b.buf + n = copy(p, buf[b.r:b.w]) + b.r += n + if b.r == b.w { + // Consumed entire buffer, release it. + b.pool.Put(b.buf) + b.buf = nil + } + return n, nil +} + +type constBufferPool struct { + buffer []byte +} + +func (p *constBufferPool) Get(int) *[]byte { + return &p.buffer +} + +func (p *constBufferPool) Put(*[]byte) {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/internal/transport/transport.go new/vendor/google.golang.org/grpc/internal/transport/transport.go --- old/vendor/google.golang.org/grpc/internal/transport/transport.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/internal/transport/transport.go 2026-05-11 15:04:29.000000000 +0200 @@ -31,6 +31,7 @@ "sync/atomic" "time" + "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" @@ -742,6 +743,22 @@ GoAwayTooManyPings GoAwayReason = 2 ) +// GoAwayInfo contains metadata about why a connection was closed. +type GoAwayInfo struct { + // Reason is the parsed reason for an HTTP/2 GOAWAY frame. + Reason GoAwayReason + // GoAwayCode is the raw HTTP/2 error code received in a GOAWAY frame. + GoAwayCode http2.ErrCode + // Err is the underlying error that caused the connection to close. It is + // populated if the connection was closed due to a socket error or context + // cancellation without receiving a GOAWAY frame. If the connection was + // closed due to a GOAWAY frame, this field will be nil. + Err error +} + +// OnCloseFunc is a callback invoked when a ClientTransport closes. +type OnCloseFunc func(GoAwayInfo) + // ContextErr converts the error from context package into a status error. func ContextErr(err error) error { switch err { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/mem/buffer_slice.go new/vendor/google.golang.org/grpc/mem/buffer_slice.go --- old/vendor/google.golang.org/grpc/mem/buffer_slice.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/mem/buffer_slice.go 2026-05-11 15:04:29.000000000 +0200 @@ -165,7 +165,7 @@ } func (r *Reader) freeFirstBufferIfEmpty() bool { - if len(r.data) == 0 || r.bufferIdx != len(r.data[0].ReadOnlyData()) { + if len(r.data) == 0 || r.bufferIdx != r.data[0].Len() { return false } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/mem/buffers.go new/vendor/google.golang.org/grpc/mem/buffers.go --- old/vendor/google.golang.org/grpc/mem/buffers.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/mem/buffers.go 2026-05-11 15:04:29.000000000 +0200 @@ -53,6 +53,10 @@ Free() // Len returns the Buffer's size. Len() int + // Slice returns a new Buffer that is a view into this buffer's data + // from [start:end). The buffer is not modified. Panics if the buffer + // has been freed or if start/end are out of bounds. + Slice(start, end int) Buffer split(n int) (left, right Buffer) read(buf []byte) (int, Buffer) @@ -180,6 +184,32 @@ return len(b.ReadOnlyData()) } +func (b *buffer) Slice(start, end int) Buffer { + if b.rootBuf == nil { + panic("Cannot slice freed buffer") + } + + data := b.data[start:end] // access the data to check slice bounds + + if len(data) == 0 { + return emptyBuffer{} + } + if len(data) == len(b.data) { + b.Ref() + return b + } + // We are creating a new reference (view) to a portion of the root buffer's + // data. Therefore, we must increment the reference count of the root buffer + // to ensure the underlying data is not freed while this view is still in + // use. + b.rootBuf.Ref() + s := newBuffer() + s.data = data + s.rootBuf = b.rootBuf + s.refs.Store(1) + return s +} + func (b *buffer) split(n int) (Buffer, Buffer) { if b.rootBuf == nil || b.rootBuf.refs.Add(1) <= 1 { panic("Cannot split freed buffer") @@ -240,6 +270,13 @@ return 0 } +func (e emptyBuffer) Slice(start, end int) Buffer { + if start != 0 || end != 0 { + panic(fmt.Sprintf("slice bounds out of range [%d:%d] with length 0", start, end)) + } + return e +} + func (e emptyBuffer) split(int) (left, right Buffer) { return e, e } @@ -264,6 +301,9 @@ // Len is a noop implementation of Len. func (s SliceBuffer) Len() int { return len(s) } +// Slice returns a new SliceBuffer that is a view into the receiver from [start:end). +func (s SliceBuffer) Slice(start, end int) Buffer { return s[start:end] } + func (s SliceBuffer) split(n int) (left, right Buffer) { return s[:n], s[n:] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/stream.go new/vendor/google.golang.org/grpc/stream.go --- old/vendor/google.golang.org/grpc/stream.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/stream.go 2026-05-11 15:04:29.000000000 +0200 @@ -21,6 +21,7 @@ import ( "context" "errors" + "fmt" "io" "math" rand "math/rand/v2" @@ -749,7 +750,7 @@ return false, err } if cs.numRetries+1 >= rp.MaxAttempts { - return false, err + return false, fmt.Errorf("max retries exhausted: failed after %d attempts: %w", cs.numRetries+1, err) } var dur time.Duration diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/google.golang.org/grpc/version.go new/vendor/google.golang.org/grpc/version.go --- old/vendor/google.golang.org/grpc/version.go 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/google.golang.org/grpc/version.go 2026-05-11 15:04:29.000000000 +0200 @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.80.0" +const Version = "1.81.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt --- old/vendor/modules.txt 2026-04-28 23:51:03.000000000 +0200 +++ new/vendor/modules.txt 2026-05-11 15:04:29.000000000 +0200 @@ -62,10 +62,10 @@ ## explicit; go 1.24.0 go.opentelemetry.io/auto/sdk go.opentelemetry.io/auto/sdk/internal/telemetry -# go.opentelemetry.io/collector/featuregate v1.57.0 +# go.opentelemetry.io/collector/featuregate v1.58.0 ## explicit; go 1.25.0 go.opentelemetry.io/collector/featuregate -# go.opentelemetry.io/collector/pdata v1.57.0 +# go.opentelemetry.io/collector/pdata v1.58.0 ## explicit; go 1.25.0 go.opentelemetry.io/collector/pdata/internal go.opentelemetry.io/collector/pdata/internal/json @@ -211,7 +211,7 @@ # go.uber.org/multierr v1.11.0 ## explicit; go 1.19 go.uber.org/multierr -# go.uber.org/zap v1.27.1 +# go.uber.org/zap v1.28.0 ## explicit; go 1.19 go.uber.org/zap go.uber.org/zap/buffer @@ -223,7 +223,7 @@ go.uber.org/zap/internal/stacktrace go.uber.org/zap/zapcore go.uber.org/zap/zapgrpc -# golang.org/x/net v0.52.0 +# golang.org/x/net v0.53.0 ## explicit; go 1.25.0 golang.org/x/net/http/httpguts golang.org/x/net/http2 @@ -233,12 +233,12 @@ golang.org/x/net/internal/httpsfv golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/sys v0.42.0 +# golang.org/x/sys v0.43.0 ## explicit; go 1.25.0 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/text v0.35.0 +# golang.org/x/text v0.36.0 ## explicit; go 1.25.0 golang.org/x/text/secure/bidirule golang.org/x/text/transform @@ -254,8 +254,8 @@ ## explicit; go 1.25.0 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.80.0 -## explicit; go 1.24.0 +# google.golang.org/grpc v1.81.0 +## explicit; go 1.25.0 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff @@ -310,6 +310,7 @@ google.golang.org/grpc/internal/syscall google.golang.org/grpc/internal/transport google.golang.org/grpc/internal/transport/networktype +google.golang.org/grpc/internal/transport/readyreader google.golang.org/grpc/keepalive google.golang.org/grpc/mem google.golang.org/grpc/metadata
