Skip to content

Commit

Permalink
add cron-jobs
Browse files Browse the repository at this point in the history
  • Loading branch information
dkazdevel committed Jun 8, 2022
1 parent 121a723 commit ca59406
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 12 deletions.
38 changes: 38 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@nestjs/core": "^7.5.1",
"@nestjs/event-emitter": "^1.1.1",
"@nestjs/platform-express": "^7.5.1",
"@nestjs/schedule": "^2.0.1",
"@nestjs/serve-static": "^2.2.2",
"@nestjs/typeorm": "^7.1.5",
"app-root-path": "^3.0.0",
Expand Down Expand Up @@ -60,6 +61,7 @@
"@nestjs/swagger": "^4.8.0",
"@nestjs/testing": "^7.5.1",
"@types/app-root-path": "^1.2.4",
"@types/cron": "^2.0.0",
"@types/express": "^4.17.8",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^26.0.15",
Expand Down
4 changes: 4 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@ import { AdvertisementsModule } from './advertisements/advertisements.module';
import {CloudinaryModule} from "./cloudinary/cloudinary.module";
import {CloudinaryProvider} from './cloudinary/cloudinary.provider';
import { BetModule } from './bet/bet.module';
import { ScheduleModule } from '@nestjs/schedule';
import { CronJobsModule } from './cron-jobs/cron-jobs.module';

@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync(typeOrmAsyncConfig),
EventEmitterModule.forRoot(),
ScheduleModule.forRoot(),
CategoriesModule,
UserModule,
AuthModule,
AdvertisementsModule,
CloudinaryModule,
BetModule,
CronJobsModule,
],
controllers: [AppController],
providers: [AppService, CloudinaryProvider],
Expand Down
3 changes: 2 additions & 1 deletion src/bet/bet.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {CreateBetDto} from './dto/createBet.dto';
import {AuthGuard} from "../auth/guards/auth.guard";
import {User} from "../user/decorators/user.decarator";
import {UserEntity} from "../user/user.entity";
import {UserBetEntity} from "./user-bet.entity";

@Controller()

Expand All @@ -14,7 +15,7 @@ export class BetController {
@Post(':slug/bet')
@UseGuards(AuthGuard)
@UsePipes(new ValidationPipe())
async createBet(@Body() createBetDto: CreateBetDto, @User() currentUser: UserEntity,@Param() slug: string) {
async createBet(@Body() createBetDto: CreateBetDto, @User() currentUser: UserEntity,@Param() slug: string): Promise<UserBetEntity> {
return this.betService.createBet(createBetDto, currentUser, slug)
}
}
8 changes: 5 additions & 3 deletions src/bet/bet.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Module} from '@nestjs/common';
import {forwardRef, Module} from '@nestjs/common';
import {BetService} from './bet.service';
import {BetController} from './bet.controller';
import {TypeOrmModule} from "@nestjs/typeorm";
Expand All @@ -8,12 +8,14 @@ import {AdvertisementsEntity} from "../advertisements/advertisements.entity";
import {BetRepository} from "./bet.repository";
import {AdvertisementsModule} from "../advertisements/advertisements.module";
import {UserModule} from "../user/user.module";
import {CronJobsModule} from "../cron-jobs/cron-jobs.module";

@Module({
imports: [TypeOrmModule.forFeature([ UserEntity, UserBetEntity, AdvertisementsEntity, BetRepository]), AdvertisementsModule, UserModule],
imports: [TypeOrmModule.forFeature([ UserEntity, UserBetEntity, AdvertisementsEntity, BetRepository]), AdvertisementsModule, UserModule,
forwardRef(()=>CronJobsModule)],
controllers: [BetController],
providers: [BetService],
exports: [BetService]
exports: [BetModule, BetService]
})
export class BetModule {
}
23 changes: 21 additions & 2 deletions src/bet/bet.repository.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {AbstractRepository, EntityRepository} from "typeorm";
import {UserBetEntity} from "./user-bet.entity";
import {Body} from "@nestjs/common";
import {Cron, SchedulerRegistry, Timeout} from '@nestjs/schedule';
import {Body, HttpException, HttpStatus, Logger} from "@nestjs/common";
import {CreateBetDto} from "./dto/createBet.dto";
import {UserEntity} from "../user/user.entity";
import {AdvertisementsEntity} from "../advertisements/advertisements.entity";
import {MessageError} from "../constans/constans";


@EntityRepository(UserBetEntity)
export class BetRepository extends AbstractRepository<UserBetEntity> {
async createBet(advert, user, betObj) {

async createBet(advert, user, betObj): Promise<UserBetEntity> {


const betData: UserBetEntity = new UserBetEntity();
Expand All @@ -25,6 +28,22 @@ export class BetRepository extends AbstractRepository<UserBetEntity> {
return await this.repository.save(betData)
}

async updateColumnIsActive(betId: number): Promise<void> {

const bet: UserBetEntity = await this.repository.findOne({
where: {id: betId}
})

if (bet.isActive) {
await this.repository.update({
id: betId
},{
isActive: false
})
}

}


}

Expand Down
27 changes: 21 additions & 6 deletions src/bet/bet.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Body, Injectable, Param} from '@nestjs/common';
import {Body, forwardRef, Inject, Injectable, Logger, Param} from '@nestjs/common';
import {CreateBetDto} from './dto/createBet.dto';
import {User} from "../user/decorators/user.decarator";
import {UserEntity} from "../user/user.entity";
Expand All @@ -7,21 +7,36 @@ import {AdvertisementsService} from "../advertisements/advertisements.service";
import slugify from "slugify";
import {UserService} from "../user/user.service";
import {AdvertisementsEntity} from "../advertisements/advertisements.entity";
import {SchedulerRegistry} from "@nestjs/schedule";
import {CronJobsService} from "../cron-jobs/cron-jobs.service";
import {UserBetEntity} from "./user-bet.entity";

@Injectable()
export class BetService {
constructor(private readonly betRepository: BetRepository,
private readonly advertisementsService: AdvertisementsService,
private readonly userService: UserService) {
constructor(
@Inject(forwardRef(() => CronJobsService))
private readonly cronJobsService: CronJobsService,
private readonly userService: UserService,
private readonly betRepository: BetRepository,
private readonly advertisementsService: AdvertisementsService,
) {
}


async createBet(@Body() bet: CreateBetDto, @User() currentUser: UserEntity, @Param() slug: string) {
async createBet(@Body() bet: CreateBetDto, @User() currentUser: UserEntity, @Param() slug: string): Promise<UserBetEntity> {
const currentSlug: string = Object.values(slug)[0]
const advert : AdvertisementsEntity = await this.advertisementsService.getAdvertisementBySlug(currentSlug);
const user : UserEntity = await this.userService.getUserById(currentUser);
const savedBet: UserBetEntity = await this.betRepository.createBet(advert, user, bet);
const expireBet: Date = savedBet.expireBet;

return await this.betRepository.createBet(advert, user, bet)
await this.cronJobsService.addCronJob(`checkBetIsActive-${currentSlug}-${user.id}-${savedBet.id}`, expireBet, savedBet.id);

return savedBet
}

async updateColumnIsActive(savedBetId: number): Promise<void> {
this.betRepository.updateColumnIsActive(savedBetId);
}

}
26 changes: 26 additions & 0 deletions src/cron-jobs/cron-jobs.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
Column,
CreateDateColumn,
Entity, JoinColumn,
ManyToOne, OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn
} from "typeorm";
import {UserEntity} from "../user/user.entity";
import {UserBetEntity} from "../bet/user-bet.entity";


@Entity({name: 'cronJobs'})
export class CronJobsEntity {
@PrimaryGeneratedColumn('increment')
id: number;

@Column("varchar")
name: string;

@CreateDateColumn()
date: Date;

@Column("integer")
betId: number;
}
13 changes: 13 additions & 0 deletions src/cron-jobs/cron-jobs.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {forwardRef, Module} from '@nestjs/common';
import { CronJobsService } from './cron-jobs.service';
import {TypeOrmModule} from "@nestjs/typeorm";
import {CronJobsRepository} from "./cron-jobs.repository";
import {BetModule} from "../bet/bet.module";

@Module({
imports: [TypeOrmModule.forFeature([CronJobsRepository]),
forwardRef(()=>BetModule)],
providers: [CronJobsService],
exports: [CronJobsModule, CronJobsService]
})
export class CronJobsModule {}
21 changes: 21 additions & 0 deletions src/cron-jobs/cron-jobs.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {AbstractRepository, EntityRepository, MoreThan} from "typeorm";
import {CronJobsEntity} from "./cron-jobs.entity";


@EntityRepository(CronJobsEntity)
export class CronJobsRepository extends AbstractRepository<CronJobsEntity> {
async saveCronJob(cronJobData: CronJobsEntity): Promise<void> {
await this.repository.save(cronJobData)
}

async findAll(): Promise<CronJobsEntity[]> {
return this.repository.find();
}

async findOne(name: string): Promise<CronJobsEntity[]> {
return this.repository.find({name: name})
}
}



75 changes: 75 additions & 0 deletions src/cron-jobs/cron-jobs.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {forwardRef, Inject, Injectable, Logger, OnModuleInit} from '@nestjs/common';
import {CronJobsRepository} from "./cron-jobs.repository";
import {CronJob} from "cron";
import {SchedulerRegistry} from "@nestjs/schedule";
import {BetRepository} from "../bet/bet.repository";
import {BetService} from "../bet/bet.service";
import {CronJobsEntity} from "./cron-jobs.entity";

@Injectable()
export class CronJobsService implements OnModuleInit {
constructor(
@Inject(forwardRef(() => BetService))
private readonly betService: BetService,
private readonly cronJobsRepository: CronJobsRepository,
private schedulerRegistry: SchedulerRegistry
) {}

private readonly logger: Logger = new Logger(BetRepository.name);

async onModuleInit(): Promise<void> {
const savedCronJobs: CronJobsEntity[] = await this.findAll();

savedCronJobs.forEach((cronJob => {
try {
this.schedulerRegistry.getCronJob(cronJob.name)
}
catch (e) {
if (cronJob.date < new Date(Date.now())) {
// достали из бд CronJob - дата старая - отправляю в betService проверить (на случай если сервер долго спал)
this.betService.updateColumnIsActive(cronJob.betId);
} else {
//достали из бд CronJob - дата новая - отправляю на добавление
this.addCronJob(cronJob.name, cronJob.date, cronJob.betId)
}
}
}))
}

async saveCronJob(name: string, expireBet: Date, savedBetId: number): Promise<void> {
const cronJobData: CronJobsEntity = new CronJobsEntity;
Object.assign(cronJobData,{
name: name,
date: (new Date(expireBet)),
betId: savedBetId
})

await this.cronJobsRepository.saveCronJob(cronJobData)
}

async findAll(): Promise<CronJobsEntity[]> {
return this.cronJobsRepository.findAll()
}

async addCronJob(name: string, expireBet: Date, savedBetId: number): Promise<void> {
// создаём CronJob
const job: CronJob = new CronJob(new Date(expireBet), () => {
this.betService.updateColumnIsActive(savedBetId);
this.logger.warn(`time for job ${name} to run`);
});

this.schedulerRegistry.addCronJob(name, job);

const foundCronJob = await this.cronJobsRepository.findOne(name);
if (foundCronJob.length === 0) {
// сохраняем новый CronJob в бд
await this.saveCronJob(name, expireBet, savedBetId)
}

job.start();

this.logger.warn(
`job ${name} added for update column at ${new Date(expireBet)}!`,
);
}
}
14 changes: 14 additions & 0 deletions src/database/migrations/1654696084741-AddCronJobs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {MigrationInterface, QueryRunner} from "typeorm";

export class AddCronJobs1654696084741 implements MigrationInterface {
name = 'AddCronJobs1654696084741'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "cronJobs" ("id" SERIAL NOT NULL, "name" character varying(300) NOT NULL, "date" TIMESTAMP NOT NULL DEFAULT now(), "betId" character varying NOT NULL, CONSTRAINT "PK_8d6395d577c72fdb5fc97a9d956" PRIMARY KEY ("id"))`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "cronJobs"`);
}

}

0 comments on commit ca59406

Please sign in to comment.