command run doesn't close when functionality contains observable calls via @nestjs/microservices clientProxy.send()
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Current behavior
When calling the logic via an HTTP request, it works as expected and request completes.
When calling the logic via a nest-commander command execution, the command hangs after successfully completing all logic.
given the following microservice client:
import { firstValueFrom } from 'rxjs';
import { Injectable } from '@nestjs/common';
import { ClientProxy, ClientProxyFactory } from '@nestjs/microservices';
import { MessagingConfigService } from './messaging.config';
@Injectable()
export class MessagingService {
private eventsClient: ClientProxy;
constructor(private readonly configService: MessagingConfigService) {
this.eventsClient = ClientProxyFactory.create(this.configService.eventsConfig);
}
send<R, I = unknown>(pattern: string, data: I) {
return this.eventsClient.send<R, I>(pattern, data);
}
async sendAsync<R, I = unknown>(pattern: string, data: I) {
return await firstValueFrom(this.send<R, I>(pattern, data));
}
emit<R, I = unknown>(pattern: string, data: I) {
return this.eventsClient.emit<R, I>(pattern, data);
}
async emitAsync<R, I = unknown>(pattern: string, data: I) {
return await firstValueFrom(this.emit<R, I>(pattern, data));
}
}
calling await this.messagingService.sendAsync('message-pattern', payload)
results in the command hanging even though this call returns values. Mind you, running the logic from an HTTP request works as expected, just not from the cli.
Also note that I have tested removing the microservice call and instead hard coded the response value, and it works fine in that instance.
Minimum reproduction code
@Command({
name: 'test',
arguments: '<action>',
description: 'test command'
})
export class TestCommand implements CommandRunner {
constructor(
private readonly messagingService: MessagingService
) {}
run(): Promise<void> {
return this.messagingService.sendAsync('test-subject', {foo: 'bar'})
}
Expected behavior
Command execution closes on response from sendAsync
call.
Package
-
nest-commander
-
nest-commander-schematics
-
nest-commander-testing
Package version
2.3.5
Node.js version
14.18.1
In which operating systems have you tested?
- macOS
- Windows
- Linux
Other
No response
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
Microservices | NestJS - A progressive Node.js framework
The ClientProxy exposes a send() method. This method is intended to call the microservice and returns an Observable with its response. Thus, we...
Read more >Testing Microservice client and `Cannot read property 'send' of ...
I'm trying to test microservice and his client controller ... and does not have any other dependency (only get() method to call rpc...
Read more >Part 5: Completing the Client Component - DEV Community
We know ClientProxy#send() returns an Observable. The job of that Observable is to consume incoming Faye messages (boxes in the diagram below) ...
Read more >Nest e2e test : Jest did not exit one second after the test run ...
It might be late but you have to call the close function from the module variable, like this: afterEach(async done => { for...
Read more >Microservices in NestJS: How to build it? A Guide - SoluteLabs
Looking at the capabilities of an application, a microservice-based architecture has gained popularity in recent years. NestJS is a Node.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Seems so, thanks for adding the modification! Glad I could help
Thanks for the reproduction. I was able to reproduce with your code (woohoo), and I have a fix for it. But first, a little background as to what’s happening:
When Nest creates a microservice client (your
EventsClient
) it’s created lazily. It’s not connected off the bat, and will only connect on manually calling connect as shown in the Nest docs (scroll up just slightly) or when the first event is sent. Because you don’t end up callingsendAsync
orsend
in yourMessagingService
code unless you usecli examples nats
, the client is never connected and you never end up having the hang. But when you do usecli examples nats
you connect the client, and it won’t disconnect until told to.There are two easy solutions here:
Change your
send
orsendAsync
to include aclose()
call forthis.eventsClient
. This works okay, but you’ll have to remember it each time, and if you end up making multiple sends you’ll end up opening and closing connections which is slowAdd an
OnModuleDestory
orOnApplicationShutdown
hook and callawait this.eventsClient.close()
. The top of the service could look like this:With this, the event was sent, response was logged, and the command exited correctly.