Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C#] Add nullable type attributes to Grpc.Core.Api #27887

Merged
merged 1 commit into from
Nov 30, 2021

Conversation

JamesNK
Copy link
Member

@JamesNK JamesNK commented Oct 31, 2021

@JamesNK JamesNK changed the title [C#] Add cancellation token overloads to streaming interfaces [C#] Add nullable type attributes to Grpc.Core.Api Oct 31, 2021
@@ -64,21 +64,21 @@ internal struct AsyncCallState
internal Task<Metadata> ResponseHeadersAsync()
{
var withState = responseHeadersAsync as Func<object, Task<Metadata>>;
return withState != null ? withState(callbackState)
return withState != null ? withState(callbackState!)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return withState != null ? withState(callbackState!)
return withState != null && callbackState != null ? withState(callbackState)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If withState is not null then callbackState has to also be not null. I chose not to use a Debug.Assert because this library targets netstandard2.0 and Debug.Assert isn't annotated there to correctly suppress the nullable warning.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. It would be neat if we could use MemberNotNullWhen but I'm not sure if it can be used in private members.

@@ -43,7 +43,7 @@ public InterceptingCallInvoker(CallInvoker invoker, Interceptor interceptor)
/// <summary>
/// Intercepts a simple blocking call with the registered interceptor.
/// </summary>
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string? host, CallOptions options, TRequest request)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we allowing a null host in all these APIs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated code passes in null -

return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);

There is also some Grpc.Core.Api code that passes down this code path, but I don't recall exactly where it is to link to it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host == null means "use the default host / authority". You can set "host" explicitly if you want to use multiple virtual hosts on a single host.
See "Authority" in https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md

So setting host=null is actually the most common use case.

@jtattermusch
Copy link
Contributor

I will look at this in detail once I successfully upgrade the dotnet SDK in the grpc/grpc repo: #27966 (it's proving difficult).

@jtattermusch
Copy link
Contributor

SDK has been updated in #27966, you can rebase now.

@jtattermusch jtattermusch added release notes: yes Indicates if PR needs to be in release notes lang/C# labels Nov 29, 2021
@jtattermusch
Copy link
Contributor

It seems like #27886 and this PR are fully independent, so I don't see a reason for this PR to be based on top of #27886.

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once the changes from #27886 are separated from this PR.

Just to double check please confirm that this feature is 100% backward compatible with older runtimes / codebases. Specifically:

  • the public API will stay binary compatible with older releases (IMHO that's because the internally, the ? and ! operators only add attributes to the the existing types (which stay unchanged)
  • unless the nullable context is explicitly set by the user in their project, the behavior of all their existing code will stay the same. (as by default the nullable checks are disabled).

@@ -43,7 +43,7 @@ public InterceptingCallInvoker(CallInvoker invoker, Interceptor interceptor)
/// <summary>
/// Intercepts a simple blocking call with the registered interceptor.
/// </summary>
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string? host, CallOptions options, TRequest request)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host == null means "use the default host / authority". You can set "host" explicitly if you want to use multiple virtual hosts on a single host.
See "Authority" in https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md

So setting host=null is actually the most common use case.

@JamesNK
Copy link
Member Author

JamesNK commented Nov 29, 2021

LGTM once the changes from #27886 are separated from this PR.

Done

  • the public API will stay binary compatible with older releases (IMHO that's because the internally, the ? and ! operators only add attributes to the the existing types (which stay unchanged)

Yes

  • unless the nullable context is explicitly set by the user in their project, the behavior of all their existing code will stay the same. (as by default the nullable checks are disabled).

Yes, it is off by default. FYI there is a chance that someone who has already enabled nullable warnings in an app could get new warnings after this assembly is annotated. That's pretty normal as more libraries are annotated, and it is only compile time warnings. There is no change at runtime.

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@apolcyn can you please add another LGTM.

@jtattermusch jtattermusch merged commit a0f30a4 into grpc:master Nov 30, 2021
@copybara-service copybara-service bot added the imported Specifies if the PR has been imported to the internal repository label Nov 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bloat/none imported Specifies if the PR has been imported to the internal repository lang/C# release notes: yes Indicates if PR needs to be in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants