Skip to content

Commit

Permalink
feat: added bull queue lessons processing
Browse files Browse the repository at this point in the history
  • Loading branch information
bddvlpr committed Jan 28, 2024
1 parent ca54a25 commit 66a77b3
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ UNTIS_USERNAME=
UNTIS_PASSWORD=
UNTIS_BASEURL=

BULL_REDIS_HOST=
BULL_REDIS_PORT=

#MAINTENANCE_TITLE=
#MAINTENANCE_DESCRIPTION=
#MAINTENANCE_LOCATION=
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/bull": "^10.0.1",
"@nestjs/cache-manager": "^2.1.0",
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^3.0.1",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/swagger": "^7.1.10",
"@willsoto/nestjs-prometheus": "^6.0.0",
"bull": "^4.11.5",
"cache-manager": "^5.2.3",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
Expand Down
13 changes: 12 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { Module } from '@nestjs/common';
import { UntisModule } from './untis/untis.module';
import { ClassesModule } from './classes/classes.module';
import { ConfigModule } from '@nestjs/config';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { SubjectsModule } from './subjects/subjects.module';
import { LessonsModule } from './lessons/lessons.module';
import { HolidaysModule } from './holidays/holidays.module';
import { MetricsModule } from './metrics/metrics.module';
import { BullModule } from '@nestjs/bull';

@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
BullModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
redis: {
host: configService.get<string>('BULL_REDIS_HOST'),
port: configService.get<number>('BULL_REDIS_PORT'),
},
}),
}),
UntisModule,
ClassesModule,
SubjectsModule,
Expand Down
41 changes: 22 additions & 19 deletions src/lessons/lessons.controller.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { InjectQueue } from '@nestjs/bull';
import {
Controller,
DefaultValuePipe,
Expand All @@ -17,17 +18,16 @@ import {
ApiQuery,
ApiTags,
} from '@nestjs/swagger';
import { UntisService } from 'src/untis/untis.service';
import { Queue } from 'bull';
import { GetLessonDto } from './dto/get-lesson.dto';
import { LessonsService } from './lessons.service';
import { FetchData, FetchIcsData } from './lessons.processor';

@ApiTags('lessons')
@Controller('lessons')
export class LessonsController {
constructor(
private readonly configService: ConfigService,
private readonly untisService: UntisService,
private readonly lessonsService: LessonsService,
@InjectQueue('lessons-queue') private readonly lessonsQueue: Queue,
) {}

@ApiOkResponse({
Expand All @@ -39,11 +39,13 @@ export class LessonsController {
})
@Get(':classId')
async getLessonsForClass(@Param('classId', ParseIntPipe) classId: number) {
const lessons = await this.untisService.fetchTimetable(
this.configService.get<number>('LESSONS_TIMETABLE_BEFORE', 7),
this.configService.get<number>('LESSONS_TIMETABLE_AFTER', 7),
const job = this.lessonsQueue.add('fetch', {
before: this.configService.get<number>('LESSONS_TIMETABLE_BEFORE', 7),
after: this.configService.get<number>('LESSONS_TIMETABLE_AFTER', 14),
classId,
);
} as FetchData);

const lessons = (await job).finished();
if (!lessons)
throw new HttpException(
'No lessons found, does class exist?',
Expand Down Expand Up @@ -76,22 +78,23 @@ export class LessonsController {
@Query('offset', new DefaultValuePipe(0), ParseIntPipe)
offset?: number,
) {
const lessons = await this.untisService.fetchTimetable(
this.configService.get<number>('LESSONS_TIMETABLE_BEFORE', 7),
this.configService.get<number>('LESSONS_TIMETABLE_AFTER', 7),
const job = this.lessonsQueue.add('fetch-ics', {
before: this.configService.get<number>('LESSONS_TIMETABLE_BEFORE', 7),
after: this.configService.get<number>('LESSONS_TIMETABLE_AFTER', 14),
classId,
);
if (!lessons)
includedSubjects,
excludedSubjects,
alarms,
offset,
} as FetchIcsData);

const ics = await (await job).finished();
if (!ics)
throw new HttpException(
'No lessons found, does class exist?',
HttpStatus.NOT_FOUND,
);

return this.lessonsService.convertToEvents(lessons, {
includedSubjects,
excludedSubjects,
alarms,
offset,
});
return ics;
}
}
14 changes: 12 additions & 2 deletions src/lessons/lessons.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ import { Module } from '@nestjs/common';
import { LessonsService } from './lessons.service';
import { LessonsController } from './lessons.controller';
import { UntisModule } from 'src/untis/untis.module';
import { BullModule } from '@nestjs/bull';
import { LessonsProcessor } from './lessons.processor';

@Module({
providers: [LessonsService],
providers: [LessonsService, LessonsProcessor],
controllers: [LessonsController],
imports: [UntisModule],
imports: [
UntisModule,
BullModule.registerQueue({
name: 'lessons-queue',
settings: {
stalledInterval: 5,
},
}),
],
})
export class LessonsModule {}
67 changes: 67 additions & 0 deletions src/lessons/lessons.processor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Process, Processor } from '@nestjs/bull';
import { Job } from 'bull';
import { UntisService } from 'src/untis/untis.service';
import { LessonsService } from './lessons.service';

export interface FetchData {
before: number;
after: number;
classId: number;
}

export interface FetchIcsData {
before: number;
after: number;
classId: number;
includedSubjects?: number[];
excludedSubjects?: number[];
alarms?: number[];
offset?: number;
}

@Processor('lessons-queue')
export class LessonsProcessor {
constructor(
private readonly untisService: UntisService,
private readonly lessonsService: LessonsService,
) {}

@Process('fetch')
async handleFetch(job: Job<FetchData>) {
const { before, after, classId } = job.data;
const lessons = await this.untisService.fetchTimetable(
before,
after,
classId,
);
await job.progress(100);
return lessons;
}

@Process('fetch-ics')
async handleFetchIcs(job: Job<FetchIcsData>) {
const {
before,
after,
classId,
includedSubjects,
excludedSubjects,
alarms,
offset,
} = job.data;
const lessons = await this.untisService.fetchTimetable(
before,
after,
classId,
);
await job.progress(50);
const ics = await this.lessonsService.convertToEvents(lessons, {
includedSubjects,
excludedSubjects,
alarms,
offset,
});
await job.progress(100);
return ics;
}
}
Loading

0 comments on commit 66a77b3

Please sign in to comment.