Skip to content

Commit

Permalink
Merge pull request #14143 from nestjs/feat/expose-listening-stream
Browse files Browse the repository at this point in the history
feat(core): expose listening stream from http adapter host
  • Loading branch information
kamilmysliwiec authored Nov 15, 2024
2 parents 491ed77 + 1a076fc commit a7b73e3
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
30 changes: 30 additions & 0 deletions packages/core/helpers/http-adapter-host.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Observable, Subject } from 'rxjs';
import { AbstractHttpAdapter } from '../adapters/http-adapter';

/**
Expand All @@ -16,6 +17,8 @@ export class HttpAdapterHost<
T extends AbstractHttpAdapter = AbstractHttpAdapter,
> {
private _httpAdapter?: T;
private _listen$ = new Subject<void>();
private isListening = false;

/**
* Accessor for the underlying `HttpAdapter`
Expand All @@ -35,4 +38,31 @@ export class HttpAdapterHost<
get httpAdapter(): T {
return this._httpAdapter;
}

/**
* Observable that allows to subscribe to the `listen` event.
* This event is emitted when the HTTP application is listening for incoming requests.
*/
get listen$(): Observable<void> {
return this._listen$.asObservable();
}

/**
* Sets the listening state of the application.
*/
set listening(listening: boolean) {
this.isListening = listening;

if (listening) {
this._listen$.next();
this._listen$.complete();
}
}

/**
* Returns a boolean indicating whether the application is listening for incoming requests.
*/
get listening(): boolean {
return this.isListening;
}
}
8 changes: 7 additions & 1 deletion packages/core/nest-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,12 @@ export class NestApplication
public async listen(port: number | string, hostname: string): Promise<any>;
public async listen(port: number | string, ...args: any[]): Promise<any> {
this.assertNotInPreviewMode('listen');
!this.isInitialized && (await this.init());

if (!this.isInitialized) {
await this.init();
}

const httpAdapterHost = this.container.getHttpAdapterHostRef();
return new Promise((resolve, reject) => {
const errorHandler = (e: any) => {
this.logger.error(e?.toString?.());
Expand Down Expand Up @@ -323,6 +327,8 @@ export class NestApplication
if (address) {
this.httpServer.removeListener('error', errorHandler);
this.isListening = true;

httpAdapterHost.listening = true;
resolve(this.httpServer);
}
if (isCallbackInOriginalArgs) {
Expand Down
18 changes: 17 additions & 1 deletion packages/core/test/helpers/application-ref-host.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@ import { expect } from 'chai';
import { HttpAdapterHost } from '../../helpers/http-adapter-host';

describe('HttpAdapterHost', () => {
const applicationRefHost = new HttpAdapterHost();
let applicationRefHost: HttpAdapterHost;
beforeEach(() => {
applicationRefHost = new HttpAdapterHost();
});

it('should wrap application reference', () => {
const ref = {};
applicationRefHost.httpAdapter = ref as any;

expect(applicationRefHost.httpAdapter).to.be.eql(ref);
});

it('should emit listen event when listening is set to true', done => {
applicationRefHost.listen$.subscribe(() => {
expect(applicationRefHost.listening).to.be.true;
done();
});
applicationRefHost.listening = true;
});

it('listening should return false if the application isnt listening yet', () => {
expect(applicationRefHost.listening).to.be.false;
});
});

0 comments on commit a7b73e3

Please sign in to comment.