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

sample(04-grpc): add independent gRPC Client / Server sample respectively #13327

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

youngkiu
Copy link
Contributor

@youngkiu youngkiu commented Mar 16, 2024

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe: Add another gRPC sample

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

https://github.com/youngkiu/nest/blob/sample/34-grpc-client-server/sample/34-grpc-client-server/README.md

  • c-2 --> s-2
[1] Calling SayHello with name:""
[1] Received error 3 INVALID_ARGUMENT: request missing required field: name
[2] Calling SayHello with name:"youngkiu"
[2] Received response Hello youngkiu
[3] Calling SayHelloStreamReply with name:""
[3] Received expected error 3 INVALID_ARGUMENT: request missing required field: name
[3] Received status with code=INVALID_ARGUMENT details=request missing required field: name
[4] Calling SayHelloStreamReply with name:"youngkiu"
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received status with code=OK details=OK
  • c-2 --> s-3
[1] Calling SayHello with name:""
[1] Received error 3 INVALID_ARGUMENT: request missing required field: name
[2] Calling SayHello with name:"youngkiu"
[2] Received response Hello youngkiu
[3] Calling SayHelloStreamReply with name:""
[3] Received status with code=OK details=OK
[4] Calling SayHelloStreamReply with name:"youngkiu"
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received response Hello youngkiu
[4] Received status with code=OK details=OK

Currently, NestJS Server produces different results.
This will be resolved when #13195 is released.

@youngkiu youngkiu changed the title sample(34-grpc-client-server): add independent gRPC Client / Server programs respectively sample(34-grpc-client-server): add independent gRPC Client / Server sample respectively Mar 16, 2024
@coveralls
Copy link

coveralls commented Mar 16, 2024

Pull Request Test Coverage Report for Build 95db5acc-385b-40ba-8c36-c49c7e046909

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 92.146%

Totals Coverage Status
Change from base Build fad5078e-9529-46ad-977e-491c6acb241f: 0.0%
Covered Lines: 6734
Relevant Lines: 7308

💛 - Coveralls

@kamilmysliwiec
Copy link
Member

I wonder if adding yet another sample to this repository doesn't create even more unnecessary overhead that we already face with updating their dependencies (maintenance burden).

Is there any way we could merge this example with the existing grpc one? If not, I'd recommend creating a separate repository instead

@youngkiu youngkiu force-pushed the sample/34-grpc-client-server branch from 7e9dc01 to 3ec5be0 Compare March 18, 2024 13:44
@youngkiu
Copy link
Contributor Author

youngkiu commented Mar 18, 2024

  1. The original 04-grpc consists of 1, 2, and 3 as one program, so it may be a little confusing for developers who are new to samples.
04-grpc Client Server
HTTP 1
gRPC 2 3
  1. I wanted to introduce ts-proto to create 04-grpc/src/hero/interfaces more easily,
  2. Usually in gRPC, client / server share proto files, so I thought a sample including the case of multiple proto files could be beneficial.

34-grpc-client-server was merged into 04-grpc, but if you still think the management burden is too high, it's okay to close the PR.

@youngkiu youngkiu changed the title sample(34-grpc-client-server): add independent gRPC Client / Server sample respectively sample(04-grpc): add independent gRPC Client / Server sample respectively Mar 18, 2024
@youngkiu youngkiu force-pushed the sample/34-grpc-client-server branch from 3ec5be0 to 00c4047 Compare March 19, 2024 23:44
Comment on lines 31 to 51
sayHelloStreamReply(request: HelloRequest): Observable<HelloReply> {
const hero$ = new ReplaySubject<HelloReply>();

if (request.name === '') {
hero$.error(
new RpcException({
code: grpc.status.INVALID_ARGUMENT,
message: 'request missing required field: name',
}),
);

return hero$.asObservable();
}

for (let i = 0; i < this.REPLY_COUNT; i++) {
hero$.next({ message: 'Hello ' + request.name });
}
hero$.complete();

return hero$.asObservable();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this using a ReplaySubject? This can be written in multiple other ways without the need of a ReplaySubject. The most concise of which would be

  sayHelloStreamReply({ name }: HelloRequest): Observable<HelloReply> {
    if (!name) {
      throw new RpcException({
        code: status.INVALID_ARGUMENT,
        message: 'request missing required field: name',
      });
    }

    return of({ message: `Hello ${name}` }).pipe(repeat(this.REPLY_COUNT));
  }

but even, so I would caution showing an example of streaming synchronous replies like this. When the list of emissions is sufficiently large this can block the event loop writing out all the messages not allowing anything else to occur. This often results in health check failures in environments like kubernetes. Ideally each emission is written out asynchronously which can be achieved with scheduled and an async scheduler.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the code review and suggestions.
I hope the sample code will greatly help developers using nest & grpc.

@youngkiu youngkiu requested a review from ssilve1989 April 15, 2024 12:19
findMany(request: Observable<HeroById>): Observable<Hero>;
}

export function HeroesServiceControllerMethods() {
Copy link
Member

@kamilmysliwiec kamilmysliwiec Nov 25, 2024

Choose a reason for hiding this comment

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

Any reason why we need this function? Is it auto-generated?

sayHelloStreamReply(request: HelloRequest): Observable<HelloReply>;
}

export function GreeterControllerMethods() {
Copy link
Member

@kamilmysliwiec kamilmysliwiec Nov 25, 2024

Choose a reason for hiding this comment

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

Any reason why we need this function? Is it auto-generated?

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

Successfully merging this pull request may close these issues.

4 participants