1 | import * as retry from 'retry';
|
2 | import * as shelljs from 'shelljs';
|
3 | import { PaperboyOptions } from './interfaces/paperboy-options.interface';
|
4 | import { logger } from './logger';
|
5 | import { NatsService } from './service/nats.service';
|
6 | import { QueueService } from './service/queue.service';
|
7 | import { RabbitMQService } from './service/rabbitmq.service';
|
8 |
|
9 | export class Paperboy {
|
10 | constructor(private readonly options: PaperboyOptions) {}
|
11 |
|
12 | public async build(buildCommand?: string): Promise<void> {
|
13 | const operation = retry.operation({
|
14 | forever: true,
|
15 | minTimeout: 1000,
|
16 | maxTimeout: 60 * 1000
|
17 | });
|
18 | await new Promise(done => {
|
19 | operation.attempt(async () => {
|
20 | try {
|
21 | await new Promise((resolve, reject) => {
|
22 | const buildProcess = shelljs.exec(
|
23 | buildCommand || this.options.command,
|
24 | {
|
25 | async: true
|
26 | }
|
27 | );
|
28 | buildProcess.on('exit', (code: number) => {
|
29 | if (code === 0) {
|
30 | resolve();
|
31 | } else {
|
32 | reject(code);
|
33 | }
|
34 | });
|
35 | });
|
36 | done();
|
37 | } catch (error) {
|
38 | logger.error(`Build process failed with exit code: ${error}`);
|
39 |
|
40 | if (operation.retry(error)) {
|
41 | logger.warn('Retrying build...');
|
42 | return;
|
43 | }
|
44 | }
|
45 | });
|
46 | });
|
47 | }
|
48 |
|
49 | public async start(): Promise<void> {
|
50 | if (
|
51 | this.options.queue === undefined ||
|
52 | this.options.queue.uri === undefined
|
53 | ) {
|
54 | throw new Error(
|
55 | 'You need to configure the queue when running paperboy start'
|
56 | );
|
57 | }
|
58 |
|
59 |
|
60 | await this.build(this.options.initialCommand);
|
61 |
|
62 |
|
63 | if (this.options.readinessHook && 0 !== this.options.readinessHook.length) {
|
64 | shelljs.exec(this.options.readinessHook);
|
65 | }
|
66 |
|
67 |
|
68 | let queueService: QueueService;
|
69 |
|
70 | if (this.options.queue.uri.startsWith('nats')) {
|
71 | queueService = new NatsService(this.options, this.build.bind(this));
|
72 | } else if (this.options.queue.uri.startsWith('amqp')) {
|
73 | queueService = new RabbitMQService(this.options, this.build.bind(this));
|
74 | } else {
|
75 | throw new Error(
|
76 | `Unknown protocol in queue URI ${this.options.queue.uri}`
|
77 | );
|
78 | }
|
79 |
|
80 | queueService.listen();
|
81 | }
|
82 | }
|