Skip to content

0.6.1

Latest

Choose a tag to compare

@pepone pepone released this 17 Sep 16:22
· 202 commits to main since this release

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 as auth2service), the generated client class, service interface and method names change (Auth2serviceClient becomes Auth2ServiceClient), and you need to update your service implementations and callers after regenerating. If a .proto file has no csharp_namespace option, the generated namespace changes to match the namespace protoc generates; the previous namespace did not compile against the protoc output.
  • 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 an rpc.status_code tag. 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 called request.Features.Set(feature) on an incoming request with the default features updated the shared FeatureCollection.Empty, and this feature then showed up in unrelated requests.
  • Fixed a bug where setting ServerAddress.Host to a bracketed IPv6 address such as [::1] produced a server address whose ToUri method threw UriFormatException. The brackets are now stripped on assignment.
  • Fixed a potential deadlock during the shutdown of a Server, ClientConnection or ConnectionCache when 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 a TruncatedData error.
  • 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 IceRpcException when 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 NotSupportedException instead of producing a corrupt payload.
  • The IceRpc.Ice package now ships Identity.ice, Locator.ice, LocatorRegistry.ice and Process.ice in its slice directory, and referencing the package adds this directory to the default IncludeDirectories metadata of every SliceCompile item. You no longer need to locate the packaged .ice files by hand. A SliceCompile item that sets IncludeDirectories explicitly 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.Generator and IceRpc.Slice.Generator now compiles in projects that don't enable ImplicitUsings.
  • Fixed the generated code for variant enums whose case names match the type names used by their fields.
  • The generated code for a Result with 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.Generator now applies cs::attribute and deprecated attributes on variant enum fields to the properties it generates for these fields.

Protobuf

  • Updated the bundled protoc compiler to 36.1 and the Google.Protobuf dependency to 3.36.1.
  • The Protobuf build tasks and protoc-gen-icerpc-csharp now map .proto file names and package names to C# exactly like protoc. In particular, the generated code for a file without the csharp_namespace option 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 AdditionalOptions metadata of ProtoFile items was not passed to protoc.
    • Removing or renaming a .proto file, or changing its OutputDir, left the previously generated C# files behind for the compiler to pick up. The next build now deletes them.
    • protoc was not run again in several situations where the generated code was out of date: a generated file older than the .proto file or one of its imports, a missing import, an updated protoc or IceRPC generator, or a change to the file's AdditionalOptions or to the project's ProtoSearchPath. In particular, you no longer need to run dotnet clean after changing AdditionalOptions.
    • Rebuilding a project (dotnet build --no-incremental, or Rebuild in the IDE) ran protoc twice per .proto file and reported warning CS2002 for the generated C# files.
  • 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, ClientConnection or ConnectionCache registered with AddIceRpcServer,
    AddIceRpcClientConnection or AddIceRpcConnectionCache failed to resolve with NotSupportedException on a system where QUIC is not available, even though the ice protocol never uses QUIC.

  • Added AddIceRpcClientConnection overloads that accept the client connection's server address, as a ServerAddress
    or a Uri, mirroring the ClientConnection constructors. 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 ClientConnection singleton, also registered as the IInvoker singleton, 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_code tag. On the interceptor, a status code other than Ok or an exception sets the activity status to Error with an error.type tag. On the middleware, a status code that reports a server failure sets the activity status to Error, while a status code that reports a problem with the request, such as NotFound or Unauthorized, leaves it unset. A cancellation by the caller's cancellation token sets the icerpc.canceled tag 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.

Full Changelog

v0.6.0...v0.6.1