feat(pipelines): list commit logs 使用直接订阅。

替代了先查询再订阅,确保数据不丢失。
This commit is contained in:
Ivan Li 2021-03-10 21:41:47 +08:00
parent d02cea2115
commit cba4c0464c
6 changed files with 18 additions and 46 deletions

View File

@ -1,4 +1,4 @@
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
import { CreatePipelineInput } from './dtos/create-pipeline.input'; import { CreatePipelineInput } from './dtos/create-pipeline.input';
import { UpdatePipelineInput } from './dtos/update-pipeline.input'; import { UpdatePipelineInput } from './dtos/update-pipeline.input';
import { Pipeline } from './pipeline.entity'; import { Pipeline } from './pipeline.entity';
@ -43,8 +43,15 @@ export class PipelinesResolver {
return await this.service.remove(id); return await this.service.remove(id);
} }
@Query(() => String) @Subscription(() => LogList, {
resolve: (value) => {
return value;
},
})
async listLogsForPipeline(@Args('id', { type: () => String }) id: string) { async listLogsForPipeline(@Args('id', { type: () => String }) id: string) {
return await this.service.listLogsForPipeline(id); const job = await this.service.listLogsForPipeline(id);
return (async function* () {
yield await job.finished();
})();
} }
} }

View File

@ -59,7 +59,7 @@ describe('PipelinesService', () => {
const add = jest.spyOn(queue, 'add'); const add = jest.spyOn(queue, 'add');
await expect( await expect(
service.listLogsForPipeline('test-pipeline'), service.listLogsForPipeline('test-pipeline'),
).resolves.toEqual(1); ).resolves.toEqual({ id: 1 });
expect(add).toBeCalledWith({ expect(add).toBeCalledWith({
project: pipeline.project, project: pipeline.project,
branch: pipeline.branch, branch: pipeline.branch,

View File

@ -50,6 +50,6 @@ export class PipelinesService extends BaseDbService<Pipeline> {
project: pipeline.project, project: pipeline.project,
branch: pipeline.branch, branch: pipeline.branch,
}); });
return job.id; return job;
} }
} }

View File

@ -1,24 +1,14 @@
import { PubSub } from 'graphql-subscriptions';
import { ReposService } from './repos.service'; import { ReposService } from './repos.service';
import { Processor, Process } from '@nestjs/bull'; import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull'; import { Job } from 'bull';
import { ListLogsOption } from './models/list-logs.options'; import { ListLogsOption } from './models/list-logs.options';
import { import { LIST_LOGS_TASK } from './repos.constants';
LIST_LOGS_DONE,
LIST_LOGS_PUB_SUB,
LIST_LOGS_TASK,
} from './repos.constants';
import { Inject } from '@nestjs/common';
@Processor(LIST_LOGS_TASK) @Processor(LIST_LOGS_TASK)
export class ListLogsConsumer { export class ListLogsConsumer {
constructor( constructor(private readonly service: ReposService) {}
private readonly service: ReposService,
@Inject(LIST_LOGS_PUB_SUB)
private readonly pubSub: PubSub,
) {}
@Process() @Process()
async listLogs(job: Job<ListLogsOption>) { async listLogs(job: Job<ListLogsOption>) {
const logs = await this.service.listLogs(job.data); const logs = await this.service.listLogs(job.data);
this.pubSub.publish(LIST_LOGS_DONE, logs); return logs;
} }
} }

View File

@ -19,15 +19,7 @@ import { ListLogsConsumer } from './list-logs.consumer';
name: LIST_LOGS_TASK, name: LIST_LOGS_TASK,
}), }),
], ],
providers: [ providers: [ReposResolver, ReposService, ListLogsConsumer],
ReposResolver,
ReposService,
ListLogsConsumer,
{
provide: LIST_LOGS_PUB_SUB,
useValue: new PubSub(),
},
],
exports: [ReposService], exports: [ReposService],
}) })
export class ReposModule {} export class ReposModule {}

View File

@ -1,21 +1,4 @@
import { LIST_LOGS_DONE, LIST_LOGS_PUB_SUB } from './repos.constants'; import { Resolver } from '@nestjs/graphql';
import { Resolver, Subscription } from '@nestjs/graphql';
import { LogList } from './dtos/log-list.model';
import { Inject } from '@nestjs/common';
import { PubSub } from 'apollo-server-express';
@Resolver() @Resolver()
export class ReposResolver { export class ReposResolver {}
constructor(
@Inject(LIST_LOGS_PUB_SUB)
private readonly pubSub: PubSub,
) {}
@Subscription(() => LogList, {
resolve: (value) => {
return value;
},
})
listLogsDone() {
return this.pubSub.asyncIterator(LIST_LOGS_DONE);
}
}