Kitex Release v0.16.2
Projects:
These release notes consolidate the changes from v0.16.0, v0.16.1, and v0.16.2. The externally announced version is v0.16.2.
Introduction to Key Changes
Announcements
- netpollmux is no longer maintained: The
pkg/remote/trans/netpollmuxpackage and the correspondingclient.WithMuxConnection/server.WithMuxTransportoptions are all marked as deprecated. netpollmux is no longer maintained. For details, see Connection Multiplexing. - Adjustments to some interfaces: No impact on regular users, but may affect those with extensions or special dependencies. For details, see the [Special Changes] section.
New Features
Binary Generic Call: Per-Request IDL Service Name, Greatly Reducing the Number of Generic Clients to Maintain
In previous versions, binary generic clients were bound to an IDL Service, requiring maintenance of a large number of clients. This version supports dynamically specifying the IDL Service Name per call, via the newly added
callopt.WithBinaryGenericIDLService(svcName)/streamcall.WithBinaryGenericIDLService(svcName)call options, and the per-call configuration takes precedence over the configuration set at client initialization. Both Ping-Pong and streaming calls are supported. For details, see Per-Call IDL Service Name.Recv Timeout Control for Streaming
Added
streaming.TimeoutConfigfor fine-grained Recv timeout control on streaming APIs. A dedicated timeout can be configured, and the newDisableCancelRemoteflag controls whether the remote stream is cascaded-cancelled after timeout. Two configuration entry points are provided:- Per-client:
client.WithStreamRecvTimeoutConfig(streaming.TimeoutConfig) - Per-call:
streamcall.WithRecvTimeoutConfig(streaming.TimeoutConfig)
When a Recv times out, a new error code
codes.RecvDeadlineExceeded(value17) is returned together with the sentinel errorkerrors.ErrStreamingTimeout, making timeout classification easier.- Per-client:
Fine-Grained Streaming Event Tracing - StreamEventHandler
A new event-callback mechanism, independent of the Tracer, can observe the core events of the streaming protocol layer (Stream start, Recv, Send, Recv Header, Stream finish), making it easy to build custom fine-grained streaming monitoring:
- Client:
client.WithStreamEventHandler(rpcinfo.ClientStreamEventHandler) - Server:
server.WithStreamEventHandler(rpcinfo.ServerStreamEventHandler)
New event types
stats.StreamStart,stats.StreamRecvHeader, andstats.StreamFinishare also added. For details, see StreamX Detailed Stream Event Tracing.- Client:
Feature/Performance Optimization
Kitex gRPC: Memory Optimization and Connection Leak Fixes
- HTTP/2 Write Buffer Reuse and Framer-Level Pooling: Supports per-connection pooling and reuse of write buffers, reducing memory usage for idle connections, suitable for scenarios where the service needs to directly handle a large number of gRPC connections. Use
client.WithGRPCReuseWriteBuffer/server.WithGRPCReuseWriteBufferto enable it, and further enable framer-level pooling viaReuseWriteBufferConfig.EnableReuseHTTP2FramerBuffer. - Client-Side Cancel Object Allocation Optimization: Reduces object allocations for unified cancel on the gRPC client side, avoiding excessive allocations in gateway scenarios where cancel operations are frequent.
- Connection Pool Leak Fix: Fixed an issue where gRPC connections were not properly recycled after being closed with no subsequent calls.
- HTTP/2 Write Buffer Reuse and Framer-Level Pooling: Supports per-connection pooling and reuse of write buffers, reducing memory usage for idle connections, suitable for scenarios where the service needs to directly handle a large number of gRPC connections. Use
TTHeader Streaming: Memory Optimization
The sender now directly reuses the underlying TCP flow control, avoiding OOM.
Service Discovery: Instance Change Event Allocation Optimization
Reduces object allocations caused by frequent downstream instance changes, lowering GC pressure. Also added
event.GetDefaultEventNum()/event.SetDefaultEventNum(num int)for tuning the default event queue capacity (default 200).RPCInfo Field Inlining
Added
rpcinfo.NewRPCInfoWithInlineFields() RPCInfo, which returns an RPCInfo with inlined sub-objects, reducing per-request pool gets and allocations. Server hot paths adopt this inlining approach, improving request handling performance.
Bug Fixes
Streaming-Related Fixes
- Recv/Send Panic on the Streaming Server Side: Streaming RPCs no longer reuse
rpcinfo, completely avoiding concurrent read/write panics onrpcinfocaused by the handler exiting early while the Stream is still being used asynchronously. - Legacy Server Middleware Extension Not Taking Effect: Fixed an issue where the extended Stream object in legacy Server Middleware was unexpectedly discarded.
- Recv/Send Panic on the Streaming Server Side: Streaming RPCs no longer reuse
Other Fixes
- rpcTimeout Ticker Leak Fix (extremely rare): Closed the ticker in the
rpcTimeoutpool to prevent resource leaks. Most online scenarios are unaffected; this issue is only noticeable in scenarios with extremely low QPS and short processing time for the API. - Panic Caused by Writing Elements of Different Types into Container Fields in Generic Calls (very rare): Writing elements of different types into the same container field could cause a panic. For example, if the field itself is
[]uint8, the first input may beuint8while the second input may bestring. After the fix, an error is returned instead of panic.
- rpcTimeout Ticker Leak Fix (extremely rare): Closed the ticker in the
Special Changes - May Affect a Small Number of Services
Mainly Breaking Changes and API deprecations. No impact on the vast majority of users; users with special dependencies should pay attention.
Breaking Changes
pkg/remote/trans/ttstream/containerPath Migration (#1952)Moved to
pkg/remote/trans/ttstream/internal/container. The package was not intended as a public API; copy the needed implementations into your own module if you depended on them.grpc.NewClientTransportCallback Timing Change (#1945)The
onClose/onGoAwaycallbacks now fire after the transport transitions to closing/draining and afterhttp2Client.muis released. Callers relying on the old ordering should migrate togrpc.NewClientTransportWithConfig.consistBalancerConsistent-Hash Algorithm Switched (#1924)The consistent-hash key/node hashing in
consistBalancerreplacesgithub.com/bytedance/gopkg/util/xxhash3withhash/maphash. Becausehash/maphashuses a per-process random seed, hash values differ across client replicas and restarts.
Deprecations
APIs are only marked as deprecated in this version; they still work, but please migrate to the new APIs at your earliest convenience.
netpollmux Fully Deprecated (#1933)
client.WithMuxConnection(connNum int)is deprecatedserver.WithMuxTransport()is deprecated- The
pkg/remote/trans/netpollmuxpackage itself is marked as deprecated and no longer maintained
See Connection Multiplexing for the rationale.
kerrors.ErrRPCFinishRestored as Deprecated Symbol (#1953)This API was removed in v0.15.0. v0.16.2 restores it as a deprecated symbol for backward compatibility with pre-v0.15 code.
Streaming-Related API Deprecations
client.WithStreamRecvTimeoutis deprecated; useclient.WithStreamRecvTimeoutConfiginstead (#1911)streamcall.WithRecvTimeoutis deprecated; usestreamcall.WithRecvTimeoutConfiginstead (#1911)
Full Change
Feature
- feat(generic): support specifying IDL Service Name per call for Binary Generic by @DMwangnima in #1928
- feat(server): add in-process LocalCaller for unary calls by @xiaost in #1930
- feat: gRPC supports reusing write buffer for each connection by @DMwangnima in #1918
- feat(streaming): add Recv timeout config and adjust gRPC error/log by @DMwangnima in #1911
- feat(streaming): support detailed tracing events by @DMwangnima in #1905
- feat(streaming): remove rpcinfo reuse for streaming by @DMwangnima in #1909
Fix
- fix(ttstream): ttstream should not recycle connection when Recv timeout with DisableCancelRemote=true by @DMwangnima in #1952
- fix(gRPC): connection pool leak when connection is closed and there are no more subsequent calls by @DMwangnima in #1945
- fix(codec): frugalAvailable for void func result structs by @xiaost in #1938
- fix(timeout): close ticker in rpctimeout pool to prevent resource leak by @DMwangnima in #1931
- fix(streaming): server-side old Stream wrapped in server MW should not be discarded by @DMwangnima in #1929
- fix(generic): panic when generic writing different elem types of container by @DMwangnima in #1926
- fix: remove streaming rpcstats Reset by @DMwangnima in #1922
- fix(ttstream): add server-side information in ttstream errBizHandlerReturnCancel exception by @DMwangnima in #1921
Optimize
- perf(gRPC): reduce object allocations on the gRPC client side for unified cancel scenarios by @DMwangnima in #1950
- optimize(gRPC): support pooling HTTP2 framer write buffer to reduce idle connection memory by @DMwangnima in #1944
- perf(server): use inline RPCInfo fields in LocalCaller by @xiaost in #1940
- optimize(discovery): reduce object allocation in discovery event queue and support changing default capacity of queue by @DMwangnima in #1939
- perf: rpcinfo inline fields by @xiaost in #1935
- optimize: remove ttstream connection write goroutine to avoid Sender OOM by @DMwangnima in #1917
Refactor
- refactor: use maphash instead of xxhash3 by @xiaost in #1924
Chore
- chore: update dependencies and add ErrRPCFinish back for compatibility by @DMwangnima in #1953
- chore(queue): remove unused field tailVersion of Queue by @DMwangnima in #1947
- chore: improve bug report issue template by @xiaost in #1941
- chore(codec): log data type before errDecodeMismatchMsgType by @xiaost in #1937
- chore(mux): deprecate thrift mux transport by @DMwangnima in #1933
- chore: change tests workflow on go 1.21-1.26 by @GuangmingLuo in #1923
- chore: update dependencies by @DMwangnima in #1912
- chore: release version v0.16.2 by @DMwangnima in #1954
- chore: release version v0.16.1 by @DMwangnima in #1919
- chore: release version v0.16.0 by @DMwangnima in #1913
Docs
- docs: add changelog by @xiaost in #1946