Search code examples
node.jsamazon-ec2timeoutnestjsazure-vm

Nestjs server doesn't respond


I am facing an issue where nestjs server after processing data doesn't respond or send response to client. I created an endpoint which takes time to process and insert the data into db. I am aware that this is not a good practice but this is required for few days. Server responds if request completes in 4m 18s but anymore seconds and it doesn't respond. No timeout or any kind of errors are thrown. I tried sending request from postman but neither server nor postman timeout. I also tried try-catch if I was missing anything. I'm deploying nest server through pm2. So I tried running server without pm2 but same result. However server responds if it is localhost, in my local environment and on the server too.

I am at a loss here about the bug and any issue. Below are the setup I'm running:

  • Azure VM - B4ms(16GB RAM, 4 vCPU)
  • Ubuntu 20.04
  • Nodejs (14.18.2)
  • Nestjs (7.0)
  • pm2 (5.1.2)

Below is my main.ts file


import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { urlencoded, json } from 'express';

async function bootstrap() {

    const app = await NestFactory.create(AppModule, {
        logger: ['log', 'error', 'verbose']
    });
    //   app.setGlobalPrefix('api');
    app.use(json({ limit: '500mb' }));
    app.use(urlencoded({ extended: true, limit: '500mb' }));

    await app.listen(3000);
}
bootstrap();

Below is my onboarding module to which endpoint controller belongs:

import { Module } from '@nestjs/common';
import { BatchService } from 'src/batch/batch.service';
import { USERS, OFFICES, USER_BATCH, BATCH, SCHEME, USER_OFFICE, DISTRICTS, ONBOARDED_BATCH_DETAILS } from '../core/constants/index';
import { UtilsService } from 'src/core/utils/utils.service';
import scheme from '../models/scheme';
import { SchemesService } from '../schemes/schemes.service';
import batch from '../models/batch';
import offices from '../models/offices';
import users from '../models/user.entity';
import user_batch from '../models/user_batch';
import { OfficeService } from '../office/office.service';
import { UserBatchService } from '../user-batch/user-batch.service';
import { UsersService } from '../users/users.service';
import { OnboardingController } from './onboarding.controller';
import { OnboardingService } from './onboarding.service';
import { UserOfficeService } from '../user-office/user-office.service';
import user_office from '../models/user_office';
import { HttpModule } from '@nestjs/axios';
import { DistrictService } from '../district/district.service';
import district from '../models/district';
import { OnboardedBatchDetailsService } from '../onboarded-batch-details/onboarded-batch-details.service';
import { onboarded_batch_details } from '../models/onboarded_batch_details';

@Module({
    imports: [
        HttpModule
    ],
  controllers: [OnboardingController],
  providers: [
      OnboardingService,
      UsersService,
      { provide: USERS, useValue: users },
      OfficeService,
      { provide: OFFICES, useValue: offices },
      UtilsService,
      UserBatchService,
      { provide: USER_BATCH, useValue: user_batch },
      BatchService,
      { provide: BATCH, useValue: batch },
      SchemesService,
      { provide: SCHEME, useValue: scheme},
      UserOfficeService,
      { provide: USER_OFFICE, useValue: user_office },
      DistrictService,
      { provide: DISTRICTS, useValue: district },
      OnboardedBatchDetailsService,
      { provide: ONBOARDED_BATCH_DETAILS, useValue: onboarded_batch_details }
    ]
})
export class OnboardingModule {}


Below is my endpoint code.

@Post('/test-batch-onboard')
    @HttpCode(200)
    async testBatchOnbard(
        @Headers('apiKey') apiKey,
        @Body() data: Array<BatchData>,
    ){
        return new Promise((resolve, reject) => {
            let t = 259000;  // 4m 19s -- no response

            let d = this.addBatchStudentData(apiKey, data);

            try{
                setTimeout(function () {
                    resolve("I'm done here after \n" + t/60000 + " mins.");
                }, t);
            }
            catch(e){
                console.log(e);
                reject(new InternalServerErrorException());
            }
        })
    }

Here is my app.module.ts


import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config/dist/config.module';
import { ScheduleModule } from '@nestjs/schedule';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AttendanceController } from './attendance/attendance.controller';
import { DatabaseModule } from './core/database/database.module';
import { AttendanceService } from './attendance/attendance.service';
import { AttendanceModule } from './attendance/attendance.module';
import { UsersModule } from './users/users.module';
import UserAttendance from './models/user_attendance';
import { BATCH, DISTRICTS, OFFICES, ONBOARDED_BATCH_DETAILS, ORGANIZATIONS, USERS, USER_ATTENDANCE, USER_BATCH } from './core/constants';
import { SchedulerModule } from './scheduler/scheduler.module';
import { ReportsModule } from './reports/reports.module';
import { OfficeModule } from './office/office.module';
import { OrganizationModule } from './organization/organization.module';
import { DailyAttendanceTasksService } from './jobs/dailyAttendanceReport.job';
import { UsersService } from './users/users.service';
import { OfficeService } from './office/office.service';
import { OrganizationService } from './organization/organization.service';
import { BatchService } from './batch/batch.service';
import { UtilsService } from './core/utils/utils.service';
import { MailgunService } from './core/utils/mailgun.service';
import { UserBatchModule } from './user-batch/user-batch.module';
import { BatchModule } from './batch/batch.module';
import { OnboardingModule } from './onboarding/onboarding.module';
import { SchemesModule } from './schemes/schemes.module';
import { UserOfficeModule } from './user-office/user-office.module';
import { DistrictService } from './district/district.service';
import { OnboardedBatchDetailsService } from './onboarded-batch-details/onboarded-batch-details.service';
import users from './models/user.entity';
import offices from './models/offices';
import organizations from './models/organizations';
import user_attendance from './models/user_attendance';
import batch from './models/batch';
import district from './models/district';
import { onboarded_batch_details } from './models/onboarded_batch_details';
import { SendBatchDataEmailJobService } from './scheduler/send-batch-data-email-job.service';


@Module({
    imports: [
        ConfigModule.forRoot({ isGlobal: true }),
        ScheduleModule.forRoot(),
        UsersModule,
        AttendanceModule,
        DatabaseModule,
        SchedulerModule,
        ReportsModule,
        OfficeModule,
        OrganizationModule,
        UserBatchModule,
        BatchModule,
        OnboardingModule,
        SchemesModule,
        UserOfficeModule,
    ],
    controllers: [AppController],
    providers: [
        AppService,
        UsersService,
        { provide: USERS, useValue: users},
        OfficeService,
        { provide: OFFICES, useValue: offices },
        OrganizationService,
        { provide: ORGANIZATIONS, useValue: organizations },
        AttendanceService,
        { provide: USER_ATTENDANCE, useValue: user_attendance },
        UsersService,
        { provide: USER_BATCH, useValue: USER_BATCH },
        BatchService,
        { provide: BATCH, useValue: batch },
        DistrictService,
        { provide: DISTRICTS, useValue: district },
        OnboardedBatchDetailsService,
        { provide: ONBOARDED_BATCH_DETAILS, useValue: onboarded_batch_details },
        DailyAttendanceTasksService,
        UtilsService,
        MailgunService,
        DistrictService,
        OnboardedBatchDetailsService
    ],
})
export class AppModule { }


Above code works in localhost in both my local envoronment and server. If you try sending a curl post request locally on server, it returns response but for any other requests, it just doesn't respond at all. I tried to increase nestjs timeout using this but it had no effect. I am searching solution for this issue since 2 days but not able to find. Any help is really appreciated. Thank you.

Edit

Above code runs normally on AWS EC2 instance and returns response.


Solution

  • I resolved the issue by increasing the default timeout of the VM. Settings required to change or increase the timeout can be accessed via Azure Powershell. Sadly, this setting is not available in Azure portal. I used Azure powershell version 7.2 and the commands to change timeout is as follows:

    1. $publicIP = Get-AzPublicIpAddress -Name '<name_of_the_ip_address_associated_with_your_VM>'
    2. $publicIP.IdleTimeoutInMinutes = "<your_time_in_mins>"
    3. Set-AzPublicIpAddress -PublicIpAddress $publicIP

    ** Kindly check for correct syntax of the commands, as different versions of powershell have different syntax.