@backstage/plugin-catalog-backend 1.12.4 → 1.13.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,68 +1,65 @@
1
1
  # @backstage/plugin-catalog-backend
2
2
 
3
- ## 1.12.4
3
+ ## 1.13.0-next.1
4
4
 
5
- ### Patch Changes
6
-
7
- - cec43bb2428a: Fixed validation of the `fullTextFilterFields` query parameter.
8
-
9
- ## 1.12.3
10
-
11
- ### Patch Changes
12
-
13
- - b0dbcb3eed4e: Fix issue with `catalogFileName` not being a required property for `/analyze-location`
5
+ ### Minor Changes
14
6
 
15
- ## 1.12.2
7
+ - 62f448edb0b5: Allow configuring the processing interval in your app-config, under the `catalog.processingInterval` key.
16
8
 
17
9
  ### Patch Changes
18
10
 
19
- - 97655cdf891f: Fix to the `limit` parameter on entity queries.
20
- - be5c0f4b7744: Update OpenAPI schema to relax the encoding validation of all request parameters.
11
+ - 1fd2109739c1: Changed the processing loop task pipeline implementation from recursive to iterative
12
+ - 0f8a97777489: Update OpenAPI schema to relax the encoding validation of all request parameters.
13
+ - 2d32d8a611e3: Fixed validation of the `fullTextFilterFields` query parameter.
14
+ - 618257f3e413: Fix issue with `catalogFileName` not being a required property for `/analyze-location`
21
15
  - Updated dependencies
22
- - @backstage/integration@1.6.2
23
- - @backstage/backend-common@0.19.4
24
- - @backstage/backend-tasks@0.5.7
25
- - @backstage/plugin-auth-node@0.2.19
26
- - @backstage/plugin-catalog-node@1.4.3
27
- - @backstage/plugin-permission-node@0.7.13
28
- - @backstage/plugin-search-backend-module-catalog@0.1.6
16
+ - @backstage/config@1.1.0-next.0
17
+ - @backstage/integration@1.7.0-next.1
18
+ - @backstage/backend-tasks@0.5.8-next.1
19
+ - @backstage/backend-common@0.19.5-next.1
20
+ - @backstage/backend-plugin-api@0.6.3-next.1
21
+ - @backstage/catalog-model@1.4.2-next.0
22
+ - @backstage/plugin-auth-node@0.3.0-next.1
23
+ - @backstage/plugin-permission-common@0.7.8-next.0
24
+ - @backstage/plugin-permission-node@0.7.14-next.1
25
+ - @backstage/plugin-search-backend-module-catalog@0.1.7-next.1
26
+ - @backstage/plugin-catalog-node@1.4.4-next.1
27
+ - @backstage/plugin-events-node@0.2.12-next.1
28
+ - @backstage/catalog-client@1.4.4-next.0
29
+ - @backstage/plugin-catalog-common@1.0.16-next.0
30
+ - @backstage/plugin-scaffolder-common@1.4.1-next.0
29
31
  - @backstage/backend-openapi-utils@0.0.3
30
- - @backstage/backend-plugin-api@0.6.2
31
- - @backstage/catalog-client@1.4.3
32
- - @backstage/catalog-model@1.4.1
33
- - @backstage/config@1.0.8
34
32
  - @backstage/errors@1.2.1
35
33
  - @backstage/types@1.1.0
36
- - @backstage/plugin-catalog-common@1.0.15
37
- - @backstage/plugin-events-node@0.2.11
38
- - @backstage/plugin-permission-common@0.7.7
39
- - @backstage/plugin-scaffolder-common@1.4.0
40
- - @backstage/plugin-search-common@1.2.5
34
+ - @backstage/plugin-search-common@1.2.6-next.0
41
35
 
42
- ## 1.12.1
36
+ ## 1.12.2-next.0
43
37
 
44
38
  ### Patch Changes
45
39
 
46
- - 550cef5818d9: Fix OpenAPI schema for the facets endpoint
40
+ - 149361e81622: Fix to the `limit` parameter on entity queries.
41
+ - 0198aa596fd9: Fixed a link to the frontend Backstage plugin that had pointed to itself.
42
+ - 41d1b2d628ea: Fix OpenAPI schema for the facets endpoint
43
+ - cfc3ca6ce060: Changes needed to support MySQL
47
44
  - Updated dependencies
48
- - @backstage/integration@1.6.1
49
- - @backstage/backend-common@0.19.3
50
- - @backstage/backend-tasks@0.5.6
51
- - @backstage/plugin-auth-node@0.2.18
52
- - @backstage/plugin-catalog-node@1.4.2
53
- - @backstage/plugin-permission-node@0.7.12
54
- - @backstage/plugin-search-backend-module-catalog@0.1.5
45
+ - @backstage/plugin-auth-node@0.3.0-next.0
46
+ - @backstage/backend-common@0.19.4-next.0
47
+ - @backstage/integration@1.7.0-next.0
48
+ - @backstage/backend-tasks@0.5.7-next.0
55
49
  - @backstage/backend-openapi-utils@0.0.3
56
- - @backstage/backend-plugin-api@0.6.1
50
+ - @backstage/backend-plugin-api@0.6.2-next.0
57
51
  - @backstage/catalog-client@1.4.3
58
52
  - @backstage/catalog-model@1.4.1
59
53
  - @backstage/config@1.0.8
60
54
  - @backstage/errors@1.2.1
61
55
  - @backstage/types@1.1.0
62
56
  - @backstage/plugin-catalog-common@1.0.15
63
- - @backstage/plugin-events-node@0.2.10
57
+ - @backstage/plugin-catalog-node@1.4.3-next.0
58
+ - @backstage/plugin-events-node@0.2.11-next.0
64
59
  - @backstage/plugin-permission-common@0.7.7
60
+ - @backstage/plugin-permission-node@0.7.13-next.0
65
61
  - @backstage/plugin-scaffolder-common@1.4.0
62
+ - @backstage/plugin-search-backend-module-catalog@0.1.6-next.0
66
63
  - @backstage/plugin-search-common@1.2.5
67
64
 
68
65
  ## 1.12.0
package/README.md CHANGED
@@ -86,5 +86,5 @@ some example entities.
86
86
 
87
87
  ## Links
88
88
 
89
- - [catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend)
89
+ - [catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog)
90
90
  is the frontend interface for this plugin.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend",
3
- "version": "1.12.4",
3
+ "version": "1.13.0-next.1",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/config.d.ts CHANGED
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { HumanDuration } from '@backstage/types';
18
+
17
19
  export interface Config {
18
20
  /**
19
21
  * Configuration options for the catalog plugin.
@@ -142,5 +144,30 @@ export interface Config {
142
144
  * "keep".
143
145
  */
144
146
  orphanStrategy?: 'keep' | 'delete';
147
+
148
+ /**
149
+ * The interval at which the catalog should process its entities.
150
+ *
151
+ * @remarks
152
+ *
153
+ * Example:
154
+ *
155
+ * ```yaml
156
+ * catalog:
157
+ * processingInterval: { minutes: 30 }
158
+ * ```
159
+ *
160
+ * Note that this is only a suggested minimum, and the actual interval may
161
+ * be longer. Internally, the catalog will scale up this number by a small
162
+ * factor and choose random numbers in that range to spread out the load. If
163
+ * the catalog is overloaded and cannot process all entities during the
164
+ * interval, the time taken between processing runs of any given entity may
165
+ * also be longer than specified here.
166
+ *
167
+ * Setting this value too low risks exhausting rate limits on external
168
+ * systems that are queried by processors, such as version control systems
169
+ * housing catalog-info files.
170
+ */
171
+ processingInterval?: HumanDuration;
145
172
  };
146
173
  }
package/dist/alpha.cjs.js CHANGED
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var alpha = require('@backstage/plugin-catalog-common/alpha');
6
6
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
7
- var CatalogBuilder = require('./cjs/CatalogBuilder-f6d92180.cjs.js');
7
+ var CatalogBuilder = require('./cjs/CatalogBuilder-e344ff09.cjs.js');
8
8
  var backendPluginApi = require('@backstage/backend-plugin-api');
9
9
  var alpha$1 = require('@backstage/plugin-catalog-node/alpha');
10
10
  var backendCommon = require('@backstage/backend-common');
@@ -36,6 +36,8 @@ require('@backstage/backend-openapi-utils');
36
36
  require('@backstage/plugin-auth-node');
37
37
  require('@backstage/plugin-permission-common');
38
38
  require('minimatch');
39
+ require('@backstage/config');
40
+ require('@backstage/types');
39
41
 
40
42
  const { conditions, createConditionalDecision } = pluginPermissionNode.createConditionExports({
41
43
  pluginId: "catalog",
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/permissions/conditionExports.ts","../src/service/CatalogPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport { permissionRules } from './rules';\n\nconst { conditions, createConditionalDecision } = createConditionExports({\n pluginId: 'catalog',\n resourceType: RESOURCE_TYPE_CATALOG_ENTITY,\n rules: permissionRules,\n});\n\n/**\n * These conditions are used when creating conditional decisions for catalog\n * entities that are returned by authorization policies.\n *\n * @alpha\n */\nexport const catalogConditions = conditions;\n\n/**\n * `createCatalogConditionalDecision` can be used when authoring policies to\n * create conditional decisions. It requires a permission of type\n * `ResourcePermission<'catalog-entity'>` to be passed as the first parameter.\n * It's recommended that you use the provided `isResourcePermission` and\n * `isPermission` helper methods to narrow the type of the permission passed to\n * the handle method as shown below.\n *\n * ```\n * // MyAuthorizationPolicy.ts\n * ...\n * import { createCatalogPolicyDecision } from '@backstage/plugin-catalog-backend';\n * import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';\n *\n * class MyAuthorizationPolicy implements PermissionPolicy {\n * async handle(request, user) {\n * ...\n *\n * if (isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)) {\n * return createCatalogConditionalDecision(\n * request.permission,\n * { anyOf: [...insert conditions here...] }\n * );\n * }\n *\n * ...\n * }\n * ```\n *\n * @alpha\n */\nexport const createCatalogConditionalDecision = createConditionalDecision;\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { CatalogBuilder } from './CatalogBuilder';\nimport {\n CatalogProcessingExtensionPoint,\n catalogProcessingExtensionPoint,\n} from '@backstage/plugin-catalog-node/alpha';\nimport {\n CatalogProcessor,\n EntityProvider,\n} from '@backstage/plugin-catalog-node';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { PlaceholderResolver } from '../modules';\n\nclass CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {\n #processors = new Array<CatalogProcessor>();\n #entityProviders = new Array<EntityProvider>();\n #placeholderResolvers: Record<string, PlaceholderResolver> = {};\n\n addProcessor(\n ...processors: Array<CatalogProcessor | Array<CatalogProcessor>>\n ): void {\n this.#processors.push(...processors.flat());\n }\n\n addEntityProvider(\n ...providers: Array<EntityProvider | Array<EntityProvider>>\n ): void {\n this.#entityProviders.push(...providers.flat());\n }\n\n addPlaceholderResolver(key: string, resolver: PlaceholderResolver) {\n if (key in this.#placeholderResolvers)\n throw new Error(\n `A placeholder resolver for '${key}' has already been set up, please check your config.`,\n );\n this.#placeholderResolvers[key] = resolver;\n }\n\n get processors() {\n return this.#processors;\n }\n\n get entityProviders() {\n return this.#entityProviders;\n }\n\n get placeholderResolvers() {\n return this.#placeholderResolvers;\n }\n}\n\n/**\n * Catalog plugin\n * @alpha\n */\nexport const catalogPlugin = createBackendPlugin({\n pluginId: 'catalog',\n register(env) {\n const processingExtensions = new CatalogExtensionPointImpl();\n // plugins depending on this API will be initialized before this plugins init method is executed.\n env.registerExtensionPoint(\n catalogProcessingExtensionPoint,\n processingExtensions,\n );\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n httpRouter: coreServices.httpRouter,\n lifecycle: coreServices.lifecycle,\n scheduler: coreServices.scheduler,\n },\n async init({\n logger,\n config,\n reader,\n database,\n permissions,\n httpRouter,\n lifecycle,\n scheduler,\n }) {\n const winstonLogger = loggerToWinstonLogger(logger);\n const builder = await CatalogBuilder.create({\n config,\n reader,\n permissions,\n database,\n scheduler,\n logger: winstonLogger,\n });\n builder.addProcessor(...processingExtensions.processors);\n builder.addEntityProvider(...processingExtensions.entityProviders);\n Object.entries(processingExtensions.placeholderResolvers).forEach(\n ([key, resolver]) => builder.setPlaceholderResolver(key, resolver),\n );\n\n const { processingEngine, router } = await builder.build();\n\n await processingEngine.start();\n lifecycle.addShutdownHook(() => processingEngine.stop());\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createConditionExports","RESOURCE_TYPE_CATALOG_ENTITY","permissionRules","createBackendPlugin","catalogProcessingExtensionPoint","coreServices","loggerToWinstonLogger","CatalogBuilder"],"mappings":"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"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":["../src/permissions/conditionExports.ts","../src/service/CatalogPlugin.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha';\nimport { createConditionExports } from '@backstage/plugin-permission-node';\nimport { permissionRules } from './rules';\n\nconst { conditions, createConditionalDecision } = createConditionExports({\n pluginId: 'catalog',\n resourceType: RESOURCE_TYPE_CATALOG_ENTITY,\n rules: permissionRules,\n});\n\n/**\n * These conditions are used when creating conditional decisions for catalog\n * entities that are returned by authorization policies.\n *\n * @alpha\n */\nexport const catalogConditions = conditions;\n\n/**\n * `createCatalogConditionalDecision` can be used when authoring policies to\n * create conditional decisions. It requires a permission of type\n * `ResourcePermission<'catalog-entity'>` to be passed as the first parameter.\n * It's recommended that you use the provided `isResourcePermission` and\n * `isPermission` helper methods to narrow the type of the permission passed to\n * the handle method as shown below.\n *\n * ```\n * // MyAuthorizationPolicy.ts\n * ...\n * import { createCatalogPolicyDecision } from '@backstage/plugin-catalog-backend';\n * import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';\n *\n * class MyAuthorizationPolicy implements PermissionPolicy {\n * async handle(request, user) {\n * ...\n *\n * if (isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)) {\n * return createCatalogConditionalDecision(\n * request.permission,\n * { anyOf: [...insert conditions here...] }\n * );\n * }\n *\n * ...\n * }\n * ```\n *\n * @alpha\n */\nexport const createCatalogConditionalDecision = createConditionalDecision;\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { CatalogBuilder } from './CatalogBuilder';\nimport {\n CatalogProcessingExtensionPoint,\n catalogProcessingExtensionPoint,\n} from '@backstage/plugin-catalog-node/alpha';\nimport {\n CatalogProcessor,\n EntityProvider,\n} from '@backstage/plugin-catalog-node';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { PlaceholderResolver } from '../modules';\n\nclass CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint {\n #processors = new Array<CatalogProcessor>();\n #entityProviders = new Array<EntityProvider>();\n #placeholderResolvers: Record<string, PlaceholderResolver> = {};\n\n addProcessor(\n ...processors: Array<CatalogProcessor | Array<CatalogProcessor>>\n ): void {\n this.#processors.push(...processors.flat());\n }\n\n addEntityProvider(\n ...providers: Array<EntityProvider | Array<EntityProvider>>\n ): void {\n this.#entityProviders.push(...providers.flat());\n }\n\n addPlaceholderResolver(key: string, resolver: PlaceholderResolver) {\n if (key in this.#placeholderResolvers)\n throw new Error(\n `A placeholder resolver for '${key}' has already been set up, please check your config.`,\n );\n this.#placeholderResolvers[key] = resolver;\n }\n\n get processors() {\n return this.#processors;\n }\n\n get entityProviders() {\n return this.#entityProviders;\n }\n\n get placeholderResolvers() {\n return this.#placeholderResolvers;\n }\n}\n\n/**\n * Catalog plugin\n * @alpha\n */\nexport const catalogPlugin = createBackendPlugin({\n pluginId: 'catalog',\n register(env) {\n const processingExtensions = new CatalogExtensionPointImpl();\n // plugins depending on this API will be initialized before this plugins init method is executed.\n env.registerExtensionPoint(\n catalogProcessingExtensionPoint,\n processingExtensions,\n );\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n httpRouter: coreServices.httpRouter,\n lifecycle: coreServices.lifecycle,\n scheduler: coreServices.scheduler,\n },\n async init({\n logger,\n config,\n reader,\n database,\n permissions,\n httpRouter,\n lifecycle,\n scheduler,\n }) {\n const winstonLogger = loggerToWinstonLogger(logger);\n const builder = await CatalogBuilder.create({\n config,\n reader,\n permissions,\n database,\n scheduler,\n logger: winstonLogger,\n });\n builder.addProcessor(...processingExtensions.processors);\n builder.addEntityProvider(...processingExtensions.entityProviders);\n Object.entries(processingExtensions.placeholderResolvers).forEach(\n ([key, resolver]) => builder.setPlaceholderResolver(key, resolver),\n );\n\n const { processingEngine, router } = await builder.build();\n\n await processingEngine.start();\n lifecycle.addShutdownHook(() => processingEngine.stop());\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createConditionExports","RESOURCE_TYPE_CATALOG_ENTITY","permissionRules","createBackendPlugin","catalogProcessingExtensionPoint","coreServices","loggerToWinstonLogger","CatalogBuilder"],"mappings":"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"}
@@ -30,7 +30,9 @@ var pluginAuthNode = require('@backstage/plugin-auth-node');
30
30
  var alpha = require('@backstage/plugin-catalog-common/alpha');
31
31
  var pluginPermissionCommon = require('@backstage/plugin-permission-common');
32
32
  var minimatch = require('minimatch');
33
+ var config = require('@backstage/config');
33
34
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
35
+ var types = require('@backstage/types');
34
36
 
35
37
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
36
38
 
@@ -1504,37 +1506,71 @@ function startTaskPipeline(options) {
1504
1506
  if (lowWatermark >= highWatermark) {
1505
1507
  throw new Error("lowWatermark must be lower than highWatermark");
1506
1508
  }
1507
- let loading = false;
1508
- let stopped = false;
1509
- let inFlightCount = 0;
1510
- async function maybeLoadMore() {
1511
- if (stopped || loading || inFlightCount > lowWatermark) {
1512
- return;
1513
- }
1514
- loading = true;
1515
- const loadCount = highWatermark - inFlightCount;
1516
- const loadedItems = await loadTasks(loadCount);
1517
- loading = false;
1518
- inFlightCount += loadedItems.length;
1519
- loadedItems.forEach((item) => {
1520
- processTask(item).finally(() => {
1521
- if (stopped) {
1522
- return;
1509
+ const state = { inFlightCount: 0 };
1510
+ const abortController = new AbortController();
1511
+ const abortSignal = abortController.signal;
1512
+ const barrier = createBarrier({
1513
+ waitTimeoutMillis: pollingIntervalMs,
1514
+ signal: abortSignal
1515
+ });
1516
+ async function pipelineLoop() {
1517
+ while (!abortSignal.aborted) {
1518
+ if (state.inFlightCount <= lowWatermark) {
1519
+ const loadCount = highWatermark - state.inFlightCount;
1520
+ const loadedItems = await Promise.resolve().then(() => loadTasks(loadCount)).catch(() => {
1521
+ return [];
1522
+ });
1523
+ if (loadedItems.length && !abortSignal.aborted) {
1524
+ state.inFlightCount += loadedItems.length;
1525
+ for (const item of loadedItems) {
1526
+ Promise.resolve().then(() => processTask(item)).catch(() => {
1527
+ }).finally(() => {
1528
+ state.inFlightCount -= 1;
1529
+ barrier.release();
1530
+ });
1531
+ }
1523
1532
  }
1524
- inFlightCount -= 1;
1525
- maybeLoadMore();
1526
- });
1527
- });
1528
- if (loadedItems.length > 1) {
1529
- maybeLoadMore();
1533
+ }
1534
+ await barrier.wait();
1530
1535
  }
1531
1536
  }
1532
- const intervalId = setInterval(() => {
1533
- maybeLoadMore();
1534
- }, pollingIntervalMs);
1537
+ pipelineLoop().catch((error) => {
1538
+ throw new Error(`Unexpected error in processing pipeline loop`, error);
1539
+ });
1535
1540
  return () => {
1536
- stopped = true;
1537
- clearInterval(intervalId);
1541
+ abortController.abort();
1542
+ barrier.destroy();
1543
+ };
1544
+ }
1545
+ function createBarrier(options) {
1546
+ const { waitTimeoutMillis, signal } = options;
1547
+ const resolvers = /* @__PURE__ */ new Set();
1548
+ function wait() {
1549
+ if (signal.aborted || !(waitTimeoutMillis > 0)) {
1550
+ return Promise.resolve();
1551
+ }
1552
+ return new Promise((resolve) => {
1553
+ const timeoutHandle = setTimeout(done, waitTimeoutMillis);
1554
+ function done() {
1555
+ resolvers.delete(done);
1556
+ clearTimeout(timeoutHandle);
1557
+ resolve();
1558
+ }
1559
+ resolvers.add(done);
1560
+ });
1561
+ }
1562
+ function release() {
1563
+ const resolversToCall = new Set(resolvers);
1564
+ resolvers.clear();
1565
+ for (const resolver of resolversToCall) {
1566
+ resolver();
1567
+ }
1568
+ }
1569
+ signal.addEventListener("abort", release);
1570
+ return {
1571
+ wait,
1572
+ release,
1573
+ destroy: () => signal.removeEventListener("abort", release)
1538
1574
  };
1539
1575
  }
1540
1576
 
@@ -6118,10 +6154,7 @@ class CatalogBuilder {
6118
6154
  __publicField(this, "processorsReplace");
6119
6155
  __publicField(this, "parser");
6120
6156
  __publicField(this, "onProcessingError");
6121
- __publicField(this, "processingInterval", createRandomProcessingInterval({
6122
- minSeconds: 100,
6123
- maxSeconds: 150
6124
- }));
6157
+ __publicField(this, "processingInterval");
6125
6158
  __publicField(this, "locationAnalyzer");
6126
6159
  __publicField(this, "permissionRules");
6127
6160
  __publicField(this, "allowedLocationType");
@@ -6139,6 +6172,9 @@ class CatalogBuilder {
6139
6172
  this.parser = void 0;
6140
6173
  this.permissionRules = Object.values(permissionRules);
6141
6174
  this.allowedLocationType = ["url"];
6175
+ this.processingInterval = CatalogBuilder.getDefaultProcessingInterval(
6176
+ env.config
6177
+ );
6142
6178
  }
6143
6179
  /**
6144
6180
  * Creates a catalog builder.
@@ -6341,7 +6377,7 @@ class CatalogBuilder {
6341
6377
  return this;
6342
6378
  }
6343
6379
  /**
6344
- * Enables the publishing of events for cloflicts in the DefaultProcessingDatabase
6380
+ * Enables the publishing of events for conflicts in the DefaultProcessingDatabase
6345
6381
  */
6346
6382
  setEventBroker(broker) {
6347
6383
  this.eventBroker = broker;
@@ -6618,6 +6654,26 @@ class CatalogBuilder {
6618
6654
  "https://backstage.io/docs/integrations/azure/org"
6619
6655
  );
6620
6656
  }
6657
+ static getDefaultProcessingInterval(config$1) {
6658
+ const processingIntervalKey = "catalog.processingInterval";
6659
+ if (!config$1.has(processingIntervalKey)) {
6660
+ return createRandomProcessingInterval({
6661
+ minSeconds: 100,
6662
+ maxSeconds: 150
6663
+ });
6664
+ }
6665
+ const duration = config.readDurationFromConfig(config$1, {
6666
+ key: processingIntervalKey
6667
+ });
6668
+ const seconds = Math.max(
6669
+ 1,
6670
+ Math.round(types.durationToMilliseconds(duration) / 1e3)
6671
+ );
6672
+ return createRandomProcessingInterval({
6673
+ minSeconds: seconds,
6674
+ maxSeconds: seconds * 1.5
6675
+ });
6676
+ }
6621
6677
  }
6622
6678
 
6623
6679
  exports.AnnotateLocationEntityProcessor = AnnotateLocationEntityProcessor;
@@ -6632,4 +6688,4 @@ exports.createCatalogPermissionRule = createCatalogPermissionRule;
6632
6688
  exports.createRandomProcessingInterval = createRandomProcessingInterval;
6633
6689
  exports.parseEntityYaml = parseEntityYaml;
6634
6690
  exports.permissionRules = permissionRules;
6635
- //# sourceMappingURL=CatalogBuilder-f6d92180.cjs.js.map
6691
+ //# sourceMappingURL=CatalogBuilder-e344ff09.cjs.js.map