-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add event for planning unit geom calculation
- Loading branch information
Showing
21 changed files
with
198 additions
and
66 deletions.
There are no files selected for viewing
25 changes: 25 additions & 0 deletions
25
api/apps/api/src/migrations/api/1632901740965-AddPlanningUnitCalculationEvents.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { MigrationInterface, QueryRunner } from 'typeorm'; | ||
|
||
export class AddPlanningUnitCalculationEvents1632901740965 | ||
implements MigrationInterface { | ||
public async up(queryRunner: QueryRunner): Promise<void> { | ||
await queryRunner.query(` | ||
INSERT INTO api_event_kinds (id) values | ||
('project.planningUnits.submitted/v1/alpha'), | ||
('project.planningUnits.finished/v1/alpha'), | ||
('project.planningUnits.failed/v1/alpha'); | ||
`); | ||
} | ||
|
||
public async down(queryRunner: QueryRunner): Promise<void> { | ||
await queryRunner.query( | ||
`DELETE FROM api_event_kinds WHERE id = 'project.planningUnits.submitted/v1/alpha';`, | ||
); | ||
await queryRunner.query( | ||
`DELETE FROM api_event_kinds WHERE id = 'project.planningUnits.finished/v1/alpha';`, | ||
); | ||
await queryRunner.query( | ||
`DELETE FROM api_event_kinds WHERE id = 'project.planningUnits.failed/v1/alpha';`, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1
api/apps/api/src/modules/planning-units/dto/create.planning-units.dto.ts
This file was deleted.
Oops, something went wrong.
6 changes: 0 additions & 6 deletions
6
api/apps/api/src/modules/planning-units/dto/update.planning-units.dto.ts
This file was deleted.
Oops, something went wrong.
18 changes: 12 additions & 6 deletions
18
api/apps/api/src/modules/planning-units/planning-units.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 72 additions & 7 deletions
79
api/apps/api/src/modules/planning-units/planning-units.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,80 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { FactoryProvider, Inject, Injectable } from '@nestjs/common'; | ||
|
||
import { QueueService } from '@marxan-api/modules/queue/queue.service'; | ||
import { CreatePlanningUnitsDTO } from './dto/create.planning-units.dto'; | ||
import { Job, Queue, QueueEvents } from 'bullmq'; | ||
import { ApiEventsService } from '@marxan-api/modules/api-events'; | ||
import { API_EVENT_KINDS } from '@marxan/api-events'; | ||
import { | ||
PlanningUnitsJob, | ||
createQueueName, | ||
} from '@marxan-jobs/planning-unit-geometry'; | ||
import { QueueBuilder, QueueEventsBuilder } from '@marxan-api/modules/queue'; | ||
|
||
export const queueToken = Symbol(`planning unit queue token`); | ||
export const queueProvider: FactoryProvider<Queue<PlanningUnitsJob, void>> = { | ||
provide: queueToken, | ||
useFactory: (builder: QueueBuilder) => builder.buildQueue(createQueueName), | ||
inject: [QueueBuilder], | ||
}; | ||
export const queueEventsToken = Symbol(`planning units queue events token`); | ||
export const queueEventsProvider: FactoryProvider<QueueEvents> = { | ||
provide: queueEventsToken, | ||
useFactory: (builder: QueueEventsBuilder) => | ||
builder.buildQueueEvents(createQueueName), | ||
inject: [QueueEventsBuilder], | ||
}; | ||
|
||
type CompletedEvent = { jobId: string; returnvalue: string }; | ||
type FailedEvent = { jobId: string; failedReason: string }; | ||
|
||
@Injectable() | ||
export class PlanningUnitsService { | ||
constructor( | ||
private readonly queueService: QueueService<CreatePlanningUnitsDTO>, | ||
) {} | ||
@Inject(queueToken) | ||
private readonly queue: Queue<PlanningUnitsJob, void>, | ||
@Inject(queueEventsToken) | ||
private readonly queueEvents: QueueEvents, | ||
private readonly events: ApiEventsService, | ||
) { | ||
this.queueEvents.on(`completed`, (data, eventId) => | ||
this.onCompleted(data, eventId), | ||
); | ||
this.queueEvents.on(`failed`, (data, eventId) => | ||
this.onFailed(data, eventId), | ||
); | ||
} | ||
|
||
public async create(jobDefinition: PlanningUnitsJob): Promise<void> { | ||
const job = await this.queue.add('create-regular-pu', jobDefinition); | ||
await this.events.createIfNotExists({ | ||
kind: API_EVENT_KINDS.project__planningUnits__submitted__v1__alpha, | ||
topic: jobDefinition.projectId, | ||
externalId: job.id, | ||
}); | ||
} | ||
|
||
private async onCompleted(data: CompletedEvent, eventId: string) { | ||
const job: Job<PlanningUnitsJob> | undefined = await this.queue.getJob( | ||
data.jobId, | ||
); | ||
if (!job) return; | ||
const { projectId } = job.data; | ||
await this.events.createIfNotExists({ | ||
kind: API_EVENT_KINDS.project__protectedAreas__finished__v1__alpha, | ||
topic: projectId, | ||
externalId: eventId, | ||
}); | ||
} | ||
|
||
public async create(creationOptions: CreatePlanningUnitsDTO): Promise<void> { | ||
await this.queueService.queue.add('create-regular-pu', creationOptions); | ||
private async onFailed(data: FailedEvent, eventId: string) { | ||
const job: Job<PlanningUnitsJob> | undefined = await this.queue.getJob( | ||
data.jobId, | ||
); | ||
if (!job) return; | ||
const { projectId } = job.data; | ||
await this.events.createIfNotExists({ | ||
kind: API_EVENT_KINDS.project__protectedAreas__finished__v1__alpha, | ||
topic: projectId, | ||
externalId: eventId, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 22 additions & 26 deletions
48
api/apps/geoprocessing/src/modules/planning-units/planning-units.worker.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,38 @@ | ||
import { Logger, Injectable } from '@nestjs/common'; | ||
import { Worker, QueueScheduler } from 'bullmq'; | ||
import { join } from 'path'; | ||
import * as config from 'config'; | ||
import { Injectable, Logger } from '@nestjs/common'; | ||
import { Worker } from 'bullmq'; | ||
import { WorkerBuilder } from '@marxan-geoprocessing/modules/worker'; | ||
import { PlanningUnitsJobProcessor } from './planning-units.job'; | ||
import { | ||
createQueueName, | ||
PlanningUnitsJob, | ||
} from '@marxan-jobs/planning-unit-geometry'; | ||
|
||
/** | ||
* @see https://docs.bullmq.io/guide/workers | ||
* | ||
* @deprecated Workers and jobs should be move to the new functionality | ||
* @debt Bullmq is expected to be supported soon in the | ||
* nest.js bull wrapper. In the meanwhile we are using Bullmq | ||
* in the worker | ||
* | ||
**/ | ||
@Injectable() | ||
export class PlanningUnitsProcessor { | ||
private readonly queueName: string = 'planning-units'; | ||
private readonly logger: Logger = new Logger(PlanningUnitsProcessor.name); | ||
public readonly worker: Worker = new Worker( | ||
this.queueName, | ||
join(__dirname, '/planning-units.job.ts'), | ||
config.get('redisApi'), | ||
); | ||
private scheduler: QueueScheduler = new QueueScheduler( | ||
this.queueName, | ||
config.get('redisApi'), | ||
); | ||
private readonly worker: Worker<PlanningUnitsJob, void>; | ||
|
||
constructor() { | ||
this.logger.debug('worker'); | ||
this.worker.on('completed', async (job) => { | ||
this.logger.debug(`Job finished ${JSON.stringify(job)}`); | ||
constructor( | ||
private readonly workerBuilder: WorkerBuilder, | ||
processor: PlanningUnitsJobProcessor, | ||
) { | ||
this.worker = workerBuilder.build<PlanningUnitsJob, void>( | ||
createQueueName, | ||
processor, | ||
); | ||
this.worker.on(`completed`, (job) => { | ||
this.logger.log(`Planning units job #${job.id} completed`); | ||
}); | ||
this.worker.on(`failed`, (job) => { | ||
this.logger.log(`Planning units job #${job.id} failed`); | ||
}); | ||
} | ||
|
||
public async onModuleDestroy(): Promise<void> { | ||
await this.scheduler.close(); | ||
await this.scheduler.disconnect(); | ||
await this.worker.close(); | ||
await this.worker.disconnect(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.