diff --git a/src/app.module.ts b/src/app.module.ts index 030be39..dac1ebc 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -37,6 +37,7 @@ import { RedisModule } from 'nestjs-redis'; debug: configService.get('env') !== 'prod', playground: true, autoSchemaFile: true, + installSubscriptionHandlers: true, }), inject: [ConfigService], }), diff --git a/src/repos/list-logs.consumer.ts b/src/repos/list-logs.consumer.ts new file mode 100644 index 0000000..0c457d2 --- /dev/null +++ b/src/repos/list-logs.consumer.ts @@ -0,0 +1,24 @@ +import { PubSub } from 'graphql-subscriptions'; +import { ReposService } from './repos.service'; +import { Processor, Process } from '@nestjs/bull'; +import { Job } from 'bull'; +import { ListLogsOption } from './models/list-logs.options'; +import { + LIST_LOGS_DONE, + LIST_LOGS_PUB_SUB, + LIST_LOGS_TASK, +} from './repos.constants'; +import { Inject } from '@nestjs/common'; +@Processor(LIST_LOGS_TASK) +export class ListLogsConsumer { + constructor( + private readonly service: ReposService, + @Inject(LIST_LOGS_PUB_SUB) + private readonly pubSub: PubSub, + ) {} + @Process() + async listLogs(job: Job) { + const logs = await this.service.listLogs(job.data); + this.pubSub.publish(LIST_LOGS_DONE, logs); + } +} diff --git a/src/repos/repos.constants.ts b/src/repos/repos.constants.ts index 6c179ab..539a6da 100644 --- a/src/repos/repos.constants.ts +++ b/src/repos/repos.constants.ts @@ -1 +1,3 @@ export const LIST_LOGS_TASK = 'LIST_LOGS_TASK'; +export const LIST_LOGS_PUB_SUB = 'LIST_LOGS_PUB_SUB'; +export const LIST_LOGS_DONE = 'LIST_LOGS_DONE'; diff --git a/src/repos/repos.module.ts b/src/repos/repos.module.ts index c4ec2e7..2b58ec7 100644 --- a/src/repos/repos.module.ts +++ b/src/repos/repos.module.ts @@ -5,10 +5,27 @@ import { ReposResolver } from './repos.resolver'; import { ReposService } from './repos.service'; import { ConfigModule } from '@nestjs/config'; import { ProjectsModule } from '../projects/projects.module'; +import { BullModule } from '@nestjs/bull'; +import { LIST_LOGS_TASK, LIST_LOGS_PUB_SUB } from './repos.constants'; +import { PubSub } from 'graphql-subscriptions'; @Module({ - imports: [TypeOrmModule.forFeature([Project]), ConfigModule, ProjectsModule], - providers: [ReposResolver, ReposService], + imports: [ + TypeOrmModule.forFeature([Project]), + ConfigModule, + ProjectsModule, + BullModule.registerQueue({ + name: LIST_LOGS_TASK, + }), + ], + providers: [ + ReposResolver, + ReposService, + { + provide: LIST_LOGS_PUB_SUB, + useValue: new PubSub(), + }, + ], exports: [ReposService], }) export class ReposModule {} diff --git a/src/repos/repos.resolver.ts b/src/repos/repos.resolver.ts index 5da9bac..b7b640f 100644 --- a/src/repos/repos.resolver.ts +++ b/src/repos/repos.resolver.ts @@ -1,26 +1,17 @@ -import { Args, Query, Resolver } from '@nestjs/graphql'; -import { ListLogsArgs } from './dtos/list-logs.args'; -import { ReposService } from './repos.service'; +import { LIST_LOGS_DONE, LIST_LOGS_PUB_SUB } from './repos.constants'; +import { Resolver, Subscription } from '@nestjs/graphql'; import { LogList } from './dtos/log-list.model'; -import { ListBranchesArgs } from './dtos/list-branches.args'; -import { BranchList } from './dtos/branch-list.model'; +import { Inject } from '@nestjs/common'; +import { PubSub } from 'apollo-server-express'; @Resolver() export class ReposResolver { - constructor(private readonly service: ReposService) {} - @Query(() => LogList) - async listLogs(@Args('listLogsArgs') dto: ListLogsArgs) { - return await this.service.listLogs(dto); - } - @Query(() => BranchList) - async listBranches( - @Args('listBranchesArgs') dto: ListBranchesArgs, - ): Promise { - return await this.service.listBranches(dto).then((data) => { - return { - ...data, - branches: Object.values(data.branches), - }; - }); + constructor( + @Inject(LIST_LOGS_PUB_SUB) + private readonly pubSub: PubSub, + ) {} + @Subscription(() => LogList) + listLogsDone() { + return this.pubSub.asyncIterator(LIST_LOGS_DONE); } } diff --git a/src/repos/repos.service.ts b/src/repos/repos.service.ts index 1f5fa9d..d90dace 100644 --- a/src/repos/repos.service.ts +++ b/src/repos/repos.service.ts @@ -1,3 +1,4 @@ +import { ListLogsOption } from './models/list-logs.options'; import { Pipeline } from './../pipelines/pipeline.entity'; import { PipelineTask } from './../pipeline-tasks/pipeline-task.entity'; import { Injectable, NotFoundException } from '@nestjs/common'; @@ -47,14 +48,9 @@ export class ReposService { return git; } - async listLogs(dto: ListLogsArgs) { - const project = await this.projectRepository.findOneOrFail({ - id: dto.projectId, - }); + async listLogs({ project, branch }: ListLogsOption) { const git = await this.getGit(project); - return await git.log( - dto.branch ? ['--branches', dto.branch, '--'] : ['--all'], - ); + return await git.log(branch ? ['--branches', branch, '--'] : ['--all']); } async listBranches(dto: ListBranchesArgs) {