Limit concurrent local TechDocs builds.

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2022-06-02 16:25:27 +02:00
parent 6888c50c47
commit 61fba6e50b
3 changed files with 42 additions and 1 deletions
@@ -159,6 +159,37 @@ describe('DocsSynchronizer', () => {
expect(DocsBuilder.prototype.build).toBeCalledTimes(1);
});
it('should limit concurrent updates', async () => {
// Given a build implementation that runs long...
MockedDocsBuilder.prototype.build.mockImplementation(
() => new Promise(() => {}),
);
(shouldCheckForUpdate as jest.Mock).mockReturnValue(true);
const entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
uid: '0',
name: 'test',
namespace: 'default',
},
};
// When more than 10 syncs are attempted...
for (let i = 0; i < 12; i++) {
docsSynchronizer.doSync({
responseHandler: mockResponseHandler,
entity,
preparers,
generators,
});
}
// Then still only 10 builds should have been triggered.
await new Promise<void>(resolve => resolve());
expect(DocsBuilder.prototype.build).toHaveBeenCalledTimes(10);
});
it('should not check for an update too often', async () => {
(shouldCheckForUpdate as jest.Mock).mockReturnValue(false);
@@ -25,6 +25,7 @@ import {
PublisherBase,
} from '@backstage/plugin-techdocs-node';
import fetch from 'node-fetch';
import pLimit, { Limit } from 'p-limit';
import { PassThrough } from 'stream';
import * as winston from 'winston';
import { TechDocsCache } from '../cache';
@@ -47,6 +48,7 @@ export class DocsSynchronizer {
private readonly config: Config;
private readonly scmIntegrations: ScmIntegrationRegistry;
private readonly cache: TechDocsCache | undefined;
private readonly buildLimiter: Limit;
constructor({
publisher,
@@ -69,6 +71,9 @@ export class DocsSynchronizer {
this.publisher = publisher;
this.scmIntegrations = scmIntegrations;
this.cache = cache;
// Single host/process: limit concurrent builds up to 10 at a time.
this.buildLimiter = pLimit(10);
}
async doSync({
@@ -123,7 +128,7 @@ export class DocsSynchronizer {
cache: this.cache,
});
const updated = await docsBuilder.build();
const updated = await this.buildLimiter(() => docsBuilder.build());
if (!updated) {
finish({ updated: false });