Repository navigation
0.6.1 is the first maintenance release for IceRPC C# 0.6. It fixes several reliability issues in the IceRPC core and Slic transport, including payload truncation, connection shutdown deadlocks, and stream leaks.
This release also includes fixes and improvements to the Ice codec, the Slice and Protobuf toolchains, dependency injection, project templates, and telemetry. In particular, the telemetry interceptor and middleware now record the outcome of each invocation and dispatch.
If you built your application with IceRPC C# 0.6.0, you can upgrade to 0.6.1 without code changes, unless the new protoc-compatible name mapping renames some of your generated Protobuf code. See the upgrade notes below.
Upgrade Notes
- Protobuf name mapping: the generated names now match
protoc's mapping. If a service or rpc name contains a digit followed by a letter (such asauth2service), the generated client class, service interface and method names change (Auth2serviceClientbecomesAuth2ServiceClient), and you need to update your service implementations and callers after regenerating. If a.protofile has nocsharp_namespaceoption, the generated namespace changes to match the namespaceprotocgenerates; the previous namespace did not compile against theprotocoutput. - Telemetry: the telemetry interceptor and middleware now record the outcome of each invocation and dispatch on the OpenTelemetry activity. A failed invocation, or a dispatch that fails with a server-side error, sets the activity status to
Error, and an activity with a response carries anrpc.status_codetag. If you have alerts or dashboards based on the activity status, these failures now show up as errors.
What's Changed
Core
- Fixed a bug where a response payload could be silently truncated: when a failure (such as an error reading the payload from the application) interrupted the streaming of this payload, the client received the truncated payload as if it was complete.
- Fixed a bug where setting a feature in a read-only feature collection updated this collection instead of throwing
InvalidOperationException. In particular, a middleware that calledrequest.Features.Set(feature)on an incoming request with the default features updated the sharedFeatureCollection.Empty, and this feature then showed up in unrelated requests. - Fixed a bug where setting
ServerAddress.Hostto a bracketed IPv6 address such as[::1]produced a server address whoseToUrimethod threwUriFormatException. The brackets are now stripped on assignment. - Fixed a potential deadlock during the shutdown of a
Server,ClientConnectionorConnectionCachewhen one of its connections was still connecting or closing at the same time.
Slic transport
- Fixed a stream leak that could eventually block all new invocations on a connection when invocations were canceled while the server was still sending their response.
- Fixed a bug where a burst of one-way requests could exceed the server's maximum unidirectional stream count and abort the connection. When this limit is reached, the client now waits for the server to consume an earlier request before sending the next one.
- Fixed two bugs triggered by canceling an invocation while its request was being sent. If the cancellation occurred before any request data was sent, the connection kept counting the canceled invocation as an open stream; after enough such cancellations, the connection reached its maximum stream count and all new invocations blocked forever. If the
cancellation occurred while the last frame of the request was being sent, the server waited forever for the rest of the request instead of failing with aTruncatedDataerror. - Fixed a bug where a connection whose underlying transport connection failed while sending could remain open until the failure was also detected while receiving. The connection is now closed as soon as the send fails, with
IceRpcError.ConnectionAborted. - Fixed a bug where a connection could hang instead of being closed by its idle timeout when the peer stopped reading while this connection was sending data. Also fixed a related bug where the graceful shutdown of a connection could fail with
IceRpcExceptionwhen the peer's keep-alive Ping arrived during this shutdown.
Ice codec
- Encoding a fully-sliced class instance with the Compact class format now fails with
NotSupportedExceptioninstead of producing a corrupt payload. - The IceRpc.Ice package now ships
Identity.ice,Locator.ice,LocatorRegistry.iceandProcess.icein itsslicedirectory, and referencing the package adds this directory to the defaultIncludeDirectoriesmetadata of everySliceCompileitem. You no longer need to locate the packaged.icefiles by hand. ASliceCompileitem that setsIncludeDirectoriesexplicitly must append%(IncludeDirectories)to its value to keep this directory.
Slice toolchain
- The bundled Slice compiler is now slicec 0.4.1. See its release notes for the compiler fixes and the new validation checks.
- The code generated by
ZeroC.Slice.GeneratorandIceRpc.Slice.Generatornow compiles in projects that don't enableImplicitUsings. - Fixed the generated code for variant enums whose case names match the type names used by their fields.
- The generated code for a
Resultwith an optional custom success or failure type (such as
Result<WellKnownTypes::TimeStamp?, string>) now compiles. - The generated code for an operation that streams an optional custom type (such as
stream WellKnownTypes::TimeStamp?) now compiles. ZeroC.Slice.Generatornow appliescs::attributeanddeprecatedattributes on variant enum fields to the properties it generates for these fields.
Protobuf
- Updated the bundled
protoccompiler to 36.1 and the Google.Protobuf dependency to 3.36.1. - The Protobuf build tasks and
protoc-gen-icerpc-csharpnow map.protofile names and package names to C# exactly likeprotoc. In particular, the generated code for a file without thecsharp_namespaceoption now uses the same namespace as the code protoc generates, and a generated file name capitalizes letters that follow digits
(sha256hash.proto→Sha256Hash.IceRpc.cs). Service and rpc names are mapped the same way (auth2service→Auth2ServiceClient). - Fixed several bugs in the IceRpc.Protobuf.Tools build tasks:
- The documented
AdditionalOptionsmetadata ofProtoFileitems was not passed toprotoc. - Removing or renaming a
.protofile, or changing itsOutputDir, left the previously generated C# files behind for the compiler to pick up. The next build now deletes them. protocwas not run again in several situations where the generated code was out of date: a generated file older than the.protofile or one of its imports, a missing import, an updatedprotocor IceRPC generator, or a change to the file'sAdditionalOptionsor to the project'sProtoSearchPath. In particular, you no longer need to rundotnet cleanafter changingAdditionalOptions.- Rebuilding a project (
dotnet build --no-incremental, or Rebuild in the IDE) ranprotoctwice per.protofile and reported warning CS2002 for the generated C# files.
- The documented
- Fixed a bug where a message with only default field values in a Protobuf stream was delivered late: the receiver got this message only when the next message or the end of the stream arrived.
Dependency injection
-
Fixed a bug where an ice
Server,ClientConnectionorConnectionCacheregistered withAddIceRpcServer,
AddIceRpcClientConnectionorAddIceRpcConnectionCachefailed to resolve withNotSupportedExceptionon a system where QUIC is not available, even though the ice protocol never uses QUIC. -
Added
AddIceRpcClientConnectionoverloads that accept the client connection's server address, as aServerAddress
or aUri, mirroring theClientConnectionconstructors. Previously, the only overload took no argument and you had to set the server address through the options pipeline:// 0.6.0 services .AddOptions<ClientConnectionOptions>() .Configure(options => options.ServerAddress = new ServerAddress(new Uri("icerpc://localhost"))); services.AddIceRpcClientConnection(); // 0.6.1 services.AddIceRpcClientConnection(new Uri("icerpc://localhost"));
Both overloads register a
ClientConnectionsingleton, also registered as theIInvokersingleton, like the parameterless overload.
Interceptors and middleware
- Fixed two bugs in the compressor interceptor and middleware:
- A compressed payload could be silently truncated: when a failure (such as an error reading the payload from the application) interrupted the sending of this payload, the peer received the truncated payload as if it was complete.
- Disposing a connection could hang forever when the peer stopped reading a compressed payload early.
- The telemetry interceptor and middleware now record the outcome of each invocation and dispatch on the OpenTelemetry activity. Every activity that has a response carries an
rpc.status_codetag. On the interceptor, a status code other thanOkor an exception sets the activity status toErrorwith anerror.typetag. On the middleware, a status code that reports a server failure sets the activity status toError, while a status code that reports a problem with the request, such asNotFoundorUnauthorized, leaves it unset. A cancellation by the caller's cancellation token sets theicerpc.canceledtag instead of marking the activity as failed.
Templates
- Fixed a bug in the non-DI templates: you could build but not run the applications created with these templates because the certificates were missing.