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

React to Response.StartAsync change #144

Closed
JamesNK opened this issue Mar 6, 2019 · 7 comments
Closed

React to Response.StartAsync change #144

JamesNK opened this issue Mar 6, 2019 · 7 comments
Assignees
Milestone

Comments

@JamesNK
Copy link
Member

JamesNK commented Mar 6, 2019

StartAsync behavior is changing with dotnet/aspnetcore#7779

Delay calling StartAsync when buffering on the server so user can send HTTP headers afterwards.

@JamesNK JamesNK self-assigned this Mar 7, 2019
@davidfowl
Copy link
Contributor

Well no, if you do that then it'll be inefficient. You want to keep calling StartAsync so that on kestrel, it'll be optimized.

@JamesNK
Copy link
Member Author

JamesNK commented Mar 7, 2019

@jtattermusch What is the current behavior of c-core when it comes to buffering? I wanted to test out whether it prevents headers from being sent but in the following code it hangs on the first await WriteAsync(message).

public override async Task SayHellos(HelloRequest request, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
    responseStream.WriteOptions = new WriteOptions(WriteFlags.BufferHint);

    for (int i = 0; i < 3; i++)
    {
        var message = $"How are you {request.Name}? {i}";
        await responseStream.WriteAsync(new HelloReply
        {
            Message = message,
            Timestamp = Timestamp.FromDateTime(DateTime.UtcNow)
        });
    }

    await responseStream.WriteAsync(new HelloReply
    {
        Message = $"Goodbye {request.Name}!",
        Timestamp = Timestamp.FromDateTime(DateTime.UtcNow)
    });

    var metadata = new Metadata();
    metadata.Add("test", "value!");

    await context.WriteResponseHeadersAsync(metadata);
}

@jkotalik
Copy link

jkotalik commented Mar 8, 2019

@JamesNK this was merged just now.

@jtattermusch
Copy link
Contributor

@jtattermusch What is the current behavior of c-core when it comes to buffering? I wanted to test out whether it prevents headers from being sent but in the following code it hangs on the first await WriteAsync(message).

public override async Task SayHellos(HelloRequest request, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
    responseStream.WriteOptions = new WriteOptions(WriteFlags.BufferHint);

    for (int i = 0; i < 3; i++)
    {
        var message = $"How are you {request.Name}? {i}";
        await responseStream.WriteAsync(new HelloReply
        {
            Message = message,
            Timestamp = Timestamp.FromDateTime(DateTime.UtcNow)
        });
    }

    await responseStream.WriteAsync(new HelloReply
    {
        Message = $"Goodbye {request.Name}!",
        Timestamp = Timestamp.FromDateTime(DateTime.UtcNow)
    });

    var metadata = new Metadata();
    metadata.Add("test", "value!");

    await context.WriteResponseHeadersAsync(metadata);
}

WriteFlag.BufferHint only affects message writes:
https://github.com/grpc/grpc/blob/aa94bab5893751284e3a75dfc42e95278b3f2334/include/grpc/impl/codegen/grpc_types.h#L426 (send_message operation in C-core terminology)

There might be a way to cork initial metadata too using this flag
https://github.com/grpc/grpc/blob/aa94bab5893751284e3a75dfc42e95278b3f2334/include/grpc/impl/codegen/grpc_types.h#L447, but I've never used it and it's not exposed in the C# layer.

It is not clear to me why your snippet hangs (I don't see anything bad with it except trying to invoke WriteReponseHeadersAsync after calling WriteAsync will throw as that's forbidden).

@jtattermusch
Copy link
Contributor

@JamesNK I ran a few experiments as of why the WriteAsync() with buffer hint hangs.
The reason seems to be that the first WriteAsync() also sends the response metadata by default which for some reasons causes trouble.
I have a repro here: grpc/grpc#18609 (note that if context.WriteResponseHeadersAsync() is run in advance, everything works as expected).

@JamesNK JamesNK modified the milestones: Preview 5, Preview 6 Apr 23, 2019
@JamesNK
Copy link
Member Author

JamesNK commented May 21, 2019

Blocked on an answer for buffering and headers interact in Grpc.Core.

@JunTaoLuo
Copy link
Contributor

We don't plan on doing further work on this right now. We can always revisit this decision in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants