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

feat(microservices): add status, unwrap, on, and other features #14142

Merged
merged 11 commits into from
Nov 20, 2024

Conversation

kamilmysliwiec
Copy link
Member

@kamilmysliwiec kamilmysliwiec commented Nov 15, 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:

What is the current behavior?

Issue Number: #14044 #11913 #14140

What is the new behavior?

Improvements: graceful reconnection for all transporters, exposed API to listen to internal events, ability to unwrap the client proxy and retrieve the underlying client/server reference, exposed status stream to subscribe to recent client status changes.

Use-cases:

  1. React to status changes from server instances or client proxies:
const serviceRef = app.connectMicroservice({
  transport: Transport.NATS,
  options: {},
});

serviceRef.status.subscribe(status => {
  console.log('Status:', status);
});

Client:

this.clientProxy.status.subscribe(status => {
  console.log('Status:', status);
});
  1. Listen to underlying, transport-specific events:
const serviceRef = app.connectMicroservice({
  transport: Transport.NATS,
  options: {},
});

serviceRef.on<NatsEvents>('disconnect', () => {
  console.log('Client disconnected');
});

Client:

// inject passing the type argument specific to the transport strategy you use
constructor(
  @Inject(MATH_SERVICE) private readonly client: ClientProxy<NatsEvents>,
) {}

// use the "on" method somewhere else
this.client.on('disconnect', () => console.log('Disconnected'));
  1. Access the underlying server/client instance:
import { NatsConnection } from 'nats';

// in the bootstrap function
const serviceRef = app.connectMicroservice({
  transport: Transport.NATS,
  options: {},
});

const connection = serviceRef.unwrap<NatsConnection>();
console.log(connection.info);

Same API for the ClientProxy class

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Copy link
Contributor

@rickdgeerling rickdgeerling left a comment

Choose a reason for hiding this comment

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

Looks great! 🙌🏻

Comment on lines +16 to +20
// To enable type safety for gRPC. This cant be uncommented by default
// because it would require the user to install the @grpc/grpc-js package even if they dont use gRPC
// Otherwise, TypeScript would fail to compile the code.
//
// type GrpcClient = import('@grpc/grpc-js').Client;
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we could add an tsconfig.json#compilerOptions.paths entry that replaces these optional dependencies with any on-compile 🤔 You'd get type-safety in the IDE, or when running tsc --noEmit

This would require a separate tsconfigs for development and compilation, and fiddling with the build system is probably not worth the small gain in DX.

Copy link
Member Author

Choose a reason for hiding this comment

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

tsc does not auto-replace paths from tsconfig.json#compilerOptions.paths (it leaves them as is)

packages/microservices/server/server-nats.ts Outdated Show resolved Hide resolved
packages/microservices/server/server-rmq.ts Outdated Show resolved Hide resolved
packages/microservices/server/server-nats.ts Outdated Show resolved Hide resolved
kamilmysliwiec and others added 2 commits November 18, 2024 15:26
Co-authored-by: Rick Dutour Geerling <rick@trilon.io>
Co-authored-by: Rick Dutour Geerling <rick@trilon.io>
}

public unwrap<T>(): T {
if (!this.mqttClient) {
Copy link

Choose a reason for hiding this comment

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

Why don't we just call connect() method here directly?

* @param event Event name
* @param callback Callback to be executed when the event is emitted
*/
public abstract on<

Choose a reason for hiding this comment

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

Hi @kamilmysliwiec,

The change here of adding abstract on and unwrap is a breaking change, as now anybody that extended this class must add these methods.

Also, the basic example here is now invalid.

Was this change intentional?

Thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

The change here of adding abstract on and unwrap is a breaking change, as now anybody that extended this class must add these methods.

This was released as part of v11 major release - breaking changes are intentional. We'll update the example shortly.

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

Successfully merging this pull request may close these issues.

4 participants