@backstage/backend-defaults 0.5.1-next.1 → 0.5.1-next.2
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 +25 -0
- package/auth/package.json +1 -1
- package/cache/package.json +1 -1
- package/database/package.json +1 -1
- package/discovery/package.json +1 -1
- package/dist/CreateBackend.cjs.js +49 -0
- package/dist/CreateBackend.cjs.js.map +1 -0
- package/dist/PackageDiscoveryService.cjs.js +109 -0
- package/dist/PackageDiscoveryService.cjs.js.map +1 -0
- package/dist/auth.cjs.js +2 -996
- package/dist/auth.cjs.js.map +1 -1
- package/dist/cache.cjs.js +4 -204
- package/dist/cache.cjs.js.map +1 -1
- package/dist/database.cjs.js +4 -957
- package/dist/database.cjs.js.map +1 -1
- package/dist/database.d.ts +4 -1
- package/dist/discovery.cjs.js +4 -92
- package/dist/discovery.cjs.js.map +1 -1
- package/dist/discoveryFeatureLoader.cjs.js +19 -0
- package/dist/discoveryFeatureLoader.cjs.js.map +1 -0
- package/dist/entrypoints/auth/DefaultAuthService.cjs.js +130 -0
- package/dist/entrypoints/auth/DefaultAuthService.cjs.js.map +1 -0
- package/dist/entrypoints/auth/JwksClient.cjs.js +49 -0
- package/dist/entrypoints/auth/JwksClient.cjs.js.map +1 -0
- package/dist/entrypoints/auth/authServiceFactory.cjs.js +57 -0
- package/dist/entrypoints/auth/authServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/ExternalTokenHandler.cjs.js +78 -0
- package/dist/entrypoints/auth/external/ExternalTokenHandler.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/helpers.cjs.js +92 -0
- package/dist/entrypoints/auth/external/helpers.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/jwks.cjs.js +63 -0
- package/dist/entrypoints/auth/external/jwks.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/legacy.cjs.js +73 -0
- package/dist/entrypoints/auth/external/legacy.cjs.js.map +1 -0
- package/dist/entrypoints/auth/external/static.cjs.js +33 -0
- package/dist/entrypoints/auth/external/static.cjs.js.map +1 -0
- package/dist/{cjs/helpers-D2f1CG0o.cjs.js → entrypoints/auth/helpers.cjs.js} +1 -1
- package/dist/entrypoints/auth/helpers.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js +147 -0
- package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/DatabaseKeyStore.cjs.js +73 -0
- package/dist/entrypoints/auth/plugin/keys/DatabaseKeyStore.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/DatabasePluginKeySource.cjs.js +75 -0
- package/dist/entrypoints/auth/plugin/keys/DatabasePluginKeySource.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.cjs.js +91 -0
- package/dist/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.cjs.js.map +1 -0
- package/dist/entrypoints/auth/plugin/keys/createPluginKeySource.cjs.js +29 -0
- package/dist/entrypoints/auth/plugin/keys/createPluginKeySource.cjs.js.map +1 -0
- package/dist/entrypoints/auth/user/UserTokenHandler.cjs.js +110 -0
- package/dist/entrypoints/auth/user/UserTokenHandler.cjs.js.map +1 -0
- package/dist/entrypoints/cache/CacheClient.cjs.js +50 -0
- package/dist/entrypoints/cache/CacheClient.cjs.js.map +1 -0
- package/dist/entrypoints/cache/CacheManager.cjs.js +147 -0
- package/dist/entrypoints/cache/CacheManager.cjs.js.map +1 -0
- package/dist/entrypoints/cache/cacheServiceFactory.cjs.js +22 -0
- package/dist/entrypoints/cache/cacheServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/cache/types.cjs.js +10 -0
- package/dist/entrypoints/cache/types.cjs.js.map +1 -0
- package/dist/entrypoints/database/DatabaseManager.cjs.js +173 -0
- package/dist/entrypoints/database/DatabaseManager.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/defaultNameOverride.cjs.js +14 -0
- package/dist/entrypoints/database/connectors/defaultNameOverride.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/defaultSchemaOverride.cjs.js +12 -0
- package/dist/entrypoints/database/connectors/defaultSchemaOverride.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/mergeDatabaseConfig.cjs.js +10 -0
- package/dist/entrypoints/database/connectors/mergeDatabaseConfig.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/mysql.cjs.js +278 -0
- package/dist/entrypoints/database/connectors/mysql.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/postgres.cjs.js +304 -0
- package/dist/entrypoints/database/connectors/postgres.cjs.js.map +1 -0
- package/dist/entrypoints/database/connectors/sqlite3.cjs.js +251 -0
- package/dist/entrypoints/database/connectors/sqlite3.cjs.js.map +1 -0
- package/dist/entrypoints/database/databaseServiceFactory.cjs.js +36 -0
- package/dist/entrypoints/database/databaseServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/discovery/HostDiscovery.cjs.js +86 -0
- package/dist/entrypoints/discovery/HostDiscovery.cjs.js.map +1 -0
- package/dist/entrypoints/discovery/discoveryServiceFactory.cjs.js +17 -0
- package/dist/entrypoints/discovery/discoveryServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/httpAuth/httpAuthServiceFactory.cjs.js +192 -0
- package/dist/entrypoints/httpAuth/httpAuthServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createAuthIntegrationRouter.cjs.js +19 -0
- package/dist/entrypoints/httpRouter/createAuthIntegrationRouter.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.cjs.js +26 -0
- package/dist/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createCredentialsBarrier.cjs.js +63 -0
- package/dist/entrypoints/httpRouter/createCredentialsBarrier.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/createLifecycleMiddleware.cjs.js +52 -0
- package/dist/entrypoints/httpRouter/createLifecycleMiddleware.cjs.js.map +1 -0
- package/dist/entrypoints/httpRouter/httpRouterServiceFactory.cjs.js +48 -0
- package/dist/entrypoints/httpRouter/httpRouterServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/lifecycle/lifecycleServiceFactory.cjs.js +88 -0
- package/dist/entrypoints/lifecycle/lifecycleServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/logger/loggerServiceFactory.cjs.js +17 -0
- package/dist/entrypoints/logger/loggerServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/permissions/permissionsServiceFactory.cjs.js +22 -0
- package/dist/entrypoints/permissions/permissionsServiceFactory.cjs.js.map +1 -0
- package/dist/{cjs/createConfigSecretEnumerator-DShyoWWL.cjs.js → entrypoints/rootConfig/createConfigSecretEnumerator.cjs.js} +1 -1
- package/dist/entrypoints/rootConfig/createConfigSecretEnumerator.cjs.js.map +1 -0
- package/dist/entrypoints/rootConfig/rootConfigServiceFactory.cjs.js +26 -0
- package/dist/entrypoints/rootConfig/rootConfigServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootHealth/rootHealthServiceFactory.cjs.js +41 -0
- package/dist/entrypoints/rootHealth/rootHealthServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/DefaultRootHttpRouter.cjs.js +77 -0
- package/dist/entrypoints/rootHttpRouter/DefaultRootHttpRouter.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/createHealthRouter.cjs.js +29 -0
- package/dist/entrypoints/rootHttpRouter/createHealthRouter.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/MiddlewareFactory.cjs.js +187 -0
- package/dist/entrypoints/rootHttpRouter/http/MiddlewareFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.cjs.js +28 -0
- package/dist/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.cjs.js.map +1 -0
- package/dist/{cjs/config-BDOwXIyo.cjs.js → entrypoints/rootHttpRouter/http/config.cjs.js} +1 -1
- package/dist/entrypoints/rootHttpRouter/http/config.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/createHttpServer.cjs.js +88 -0
- package/dist/entrypoints/rootHttpRouter/http/createHttpServer.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/getGeneratedCertificate.cjs.js +130 -0
- package/dist/entrypoints/rootHttpRouter/http/getGeneratedCertificate.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/readCorsOptions.cjs.js +51 -0
- package/dist/entrypoints/rootHttpRouter/http/readCorsOptions.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/http/readHelmetOptions.cjs.js +62 -0
- package/dist/entrypoints/rootHttpRouter/http/readHelmetOptions.cjs.js.map +1 -0
- package/dist/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.cjs.js +73 -0
- package/dist/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootLifecycle/rootLifecycleServiceFactory.cjs.js +76 -0
- package/dist/entrypoints/rootLifecycle/rootLifecycleServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/rootLogger/WinstonLogger.cjs.js +114 -0
- package/dist/entrypoints/rootLogger/WinstonLogger.cjs.js.map +1 -0
- package/dist/entrypoints/rootLogger/rootLoggerServiceFactory.cjs.js +30 -0
- package/dist/entrypoints/rootLogger/rootLoggerServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/database/migrateBackendTasks.cjs.js +18 -0
- package/dist/entrypoints/scheduler/database/migrateBackendTasks.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/database/tables.cjs.js +8 -0
- package/dist/entrypoints/scheduler/database/tables.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/DefaultSchedulerService.cjs.js +37 -0
- package/dist/entrypoints/scheduler/lib/DefaultSchedulerService.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/LocalTaskWorker.cjs.js +105 -0
- package/dist/entrypoints/scheduler/lib/LocalTaskWorker.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.cjs.js +138 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.cjs.js +59 -0
- package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js +275 -0
- package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/types.cjs.js +60 -0
- package/dist/entrypoints/scheduler/lib/types.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/lib/util.cjs.js +66 -0
- package/dist/entrypoints/scheduler/lib/util.cjs.js.map +1 -0
- package/dist/entrypoints/scheduler/schedulerServiceFactory.cjs.js +19 -0
- package/dist/entrypoints/scheduler/schedulerServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.cjs.js +274 -0
- package/dist/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js +261 -0
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/AzureUrlReader.cjs.js +148 -0
- package/dist/entrypoints/urlReader/lib/AzureUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/BitbucketCloudUrlReader.cjs.js +174 -0
- package/dist/entrypoints/urlReader/lib/BitbucketCloudUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/BitbucketServerUrlReader.cjs.js +170 -0
- package/dist/entrypoints/urlReader/lib/BitbucketServerUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/BitbucketUrlReader.cjs.js +182 -0
- package/dist/entrypoints/urlReader/lib/BitbucketUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/FetchUrlReader.cjs.js +132 -0
- package/dist/entrypoints/urlReader/lib/FetchUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GerritUrlReader.cjs.js +147 -0
- package/dist/entrypoints/urlReader/lib/GerritUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GiteaUrlReader.cjs.js +122 -0
- package/dist/entrypoints/urlReader/lib/GiteaUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GithubUrlReader.cjs.js +226 -0
- package/dist/entrypoints/urlReader/lib/GithubUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GitlabUrlReader.cjs.js +277 -0
- package/dist/entrypoints/urlReader/lib/GitlabUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/GoogleGcsUrlReader.cjs.js +129 -0
- package/dist/entrypoints/urlReader/lib/GoogleGcsUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/HarnessUrlReader.cjs.js +120 -0
- package/dist/entrypoints/urlReader/lib/HarnessUrlReader.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/ReadUrlResponseFactory.cjs.js +49 -0
- package/dist/entrypoints/urlReader/lib/ReadUrlResponseFactory.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/UrlReaderPredicateMux.cjs.js +46 -0
- package/dist/entrypoints/urlReader/lib/UrlReaderPredicateMux.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/UrlReaders.cjs.js +68 -0
- package/dist/entrypoints/urlReader/lib/UrlReaders.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.cjs.js +46 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadableArrayResponse.cjs.js +78 -0
- package/dist/entrypoints/urlReader/lib/tree/ReadableArrayResponse.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/TarArchiveResponse.cjs.js +147 -0
- package/dist/entrypoints/urlReader/lib/tree/TarArchiveResponse.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/ZipArchiveResponse.cjs.js +161 -0
- package/dist/entrypoints/urlReader/lib/tree/ZipArchiveResponse.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/tree/util.cjs.js +28 -0
- package/dist/entrypoints/urlReader/lib/tree/util.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/lib/util.cjs.js +11 -0
- package/dist/entrypoints/urlReader/lib/util.cjs.js.map +1 -0
- package/dist/entrypoints/urlReader/urlReaderServiceFactory.cjs.js +29 -0
- package/dist/entrypoints/urlReader/urlReaderServiceFactory.cjs.js.map +1 -0
- package/dist/entrypoints/userInfo/DefaultUserInfoService.cjs.js +59 -0
- package/dist/entrypoints/userInfo/DefaultUserInfoService.cjs.js.map +1 -0
- package/dist/entrypoints/userInfo/userInfoServiceFactory.cjs.js +17 -0
- package/dist/entrypoints/userInfo/userInfoServiceFactory.cjs.js.map +1 -0
- package/dist/httpAuth.cjs.js +3 -187
- package/dist/httpAuth.cjs.js.map +1 -1
- package/dist/httpRouter.cjs.js +2 -166
- package/dist/httpRouter.cjs.js.map +1 -1
- package/dist/index.cjs.js +4 -160
- package/dist/index.cjs.js.map +1 -1
- package/dist/lib/escapeRegExp.cjs.js +8 -0
- package/dist/lib/escapeRegExp.cjs.js.map +1 -0
- package/dist/lifecycle.cjs.js +3 -58
- package/dist/lifecycle.cjs.js.map +1 -1
- package/dist/logger.cjs.js +3 -12
- package/dist/logger.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +252 -0
- package/dist/package.json.cjs.js.map +1 -0
- package/dist/permissions.cjs.js +3 -17
- package/dist/permissions.cjs.js.map +1 -1
- package/dist/rootConfig.cjs.js +4 -22
- package/dist/rootConfig.cjs.js.map +1 -1
- package/dist/rootHealth.cjs.js +3 -35
- package/dist/rootHealth.cjs.js.map +1 -1
- package/dist/rootHttpRouter.cjs.js +15 -651
- package/dist/rootHttpRouter.cjs.js.map +1 -1
- package/dist/rootLifecycle.cjs.js +3 -70
- package/dist/rootLifecycle.cjs.js.map +1 -1
- package/dist/rootLogger.cjs.js +4 -137
- package/dist/rootLogger.cjs.js.map +1 -1
- package/dist/scheduler.cjs.js +4 -693
- package/dist/scheduler.cjs.js.map +1 -1
- package/dist/scheduler.d.ts +2 -1
- package/dist/urlReader.cjs.js +32 -2962
- package/dist/urlReader.cjs.js.map +1 -1
- package/dist/userInfo.cjs.js +2 -64
- package/dist/userInfo.cjs.js.map +1 -1
- package/httpAuth/package.json +1 -1
- package/httpRouter/package.json +1 -1
- package/lifecycle/package.json +1 -1
- package/logger/package.json +1 -1
- package/package.json +13 -13
- package/permissions/package.json +1 -1
- package/rootConfig/package.json +1 -1
- package/rootHealth/package.json +1 -1
- package/rootHttpRouter/package.json +1 -1
- package/rootLifecycle/package.json +1 -1
- package/rootLogger/package.json +1 -1
- package/scheduler/package.json +1 -1
- package/urlReader/package.json +1 -1
- package/userInfo/package.json +1 -1
- package/dist/cjs/config-BDOwXIyo.cjs.js.map +0 -1
- package/dist/cjs/createConfigSecretEnumerator-DShyoWWL.cjs.js.map +0 -1
- package/dist/cjs/helpers-D2f1CG0o.cjs.js.map +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var tables = require('./tables.cjs.js');
|
|
5
|
+
|
|
6
|
+
async function migrateBackendTasks(knex) {
|
|
7
|
+
const migrationsDir = backendPluginApi.resolvePackagePath(
|
|
8
|
+
"@backstage/backend-defaults",
|
|
9
|
+
"migrations/scheduler"
|
|
10
|
+
);
|
|
11
|
+
await knex.migrate.latest({
|
|
12
|
+
directory: migrationsDir,
|
|
13
|
+
tableName: tables.DB_MIGRATIONS_TABLE
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.migrateBackendTasks = migrateBackendTasks;
|
|
18
|
+
//# sourceMappingURL=migrateBackendTasks.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrateBackendTasks.cjs.js","sources":["../../../../src/entrypoints/scheduler/database/migrateBackendTasks.ts"],"sourcesContent":["/*\n * Copyright 2021 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 { resolvePackagePath } from '@backstage/backend-plugin-api';\nimport { Knex } from 'knex';\nimport { DB_MIGRATIONS_TABLE } from './tables';\n\nexport async function migrateBackendTasks(knex: Knex): Promise<void> {\n const migrationsDir = resolvePackagePath(\n '@backstage/backend-defaults',\n 'migrations/scheduler',\n );\n\n await knex.migrate.latest({\n directory: migrationsDir,\n tableName: DB_MIGRATIONS_TABLE,\n });\n}\n"],"names":["resolvePackagePath","DB_MIGRATIONS_TABLE"],"mappings":";;;;;AAoBA,eAAsB,oBAAoB,IAA2B,EAAA;AACnE,EAAA,MAAM,aAAgB,GAAAA,mCAAA;AAAA,IACpB,6BAAA;AAAA,IACA,sBAAA;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,IAAA,CAAK,QAAQ,MAAO,CAAA;AAAA,IACxB,SAAW,EAAA,aAAA;AAAA,IACX,SAAW,EAAAC,0BAAA;AAAA,GACZ,CAAA,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DB_MIGRATIONS_TABLE = "backstage_backend_tasks__knex_migrations";
|
|
4
|
+
const DB_TASKS_TABLE = "backstage_backend_tasks__tasks";
|
|
5
|
+
|
|
6
|
+
exports.DB_MIGRATIONS_TABLE = DB_MIGRATIONS_TABLE;
|
|
7
|
+
exports.DB_TASKS_TABLE = DB_TASKS_TABLE;
|
|
8
|
+
//# sourceMappingURL=tables.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.cjs.js","sources":["../../../../src/entrypoints/scheduler/database/tables.ts"],"sourcesContent":["/*\n * Copyright 2021 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\nexport const DB_MIGRATIONS_TABLE = 'backstage_backend_tasks__knex_migrations';\nexport const DB_TASKS_TABLE = 'backstage_backend_tasks__tasks';\n\nexport type DbTasksRow = {\n id: string;\n settings_json: string;\n next_run_start_at: Date;\n current_run_ticket?: string;\n current_run_started_at?: Date | string;\n current_run_expires_at?: Date | string;\n};\n"],"names":[],"mappings":";;AAgBO,MAAM,mBAAsB,GAAA,2CAAA;AAC5B,MAAM,cAAiB,GAAA;;;;;"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lodash = require('lodash');
|
|
4
|
+
var luxon = require('luxon');
|
|
5
|
+
var migrateBackendTasks = require('../database/migrateBackendTasks.cjs.js');
|
|
6
|
+
var PluginTaskSchedulerImpl = require('./PluginTaskSchedulerImpl.cjs.js');
|
|
7
|
+
var PluginTaskSchedulerJanitor = require('./PluginTaskSchedulerJanitor.cjs.js');
|
|
8
|
+
|
|
9
|
+
class DefaultSchedulerService {
|
|
10
|
+
static create(options) {
|
|
11
|
+
const databaseFactory = lodash.once(async () => {
|
|
12
|
+
const knex = await options.database.getClient();
|
|
13
|
+
if (!options.database.migrations?.skip) {
|
|
14
|
+
await migrateBackendTasks.migrateBackendTasks(knex);
|
|
15
|
+
}
|
|
16
|
+
if (process.env.NODE_ENV !== "test") {
|
|
17
|
+
const abortController = new AbortController();
|
|
18
|
+
const janitor = new PluginTaskSchedulerJanitor.PluginTaskSchedulerJanitor({
|
|
19
|
+
knex,
|
|
20
|
+
waitBetweenRuns: luxon.Duration.fromObject({ minutes: 1 }),
|
|
21
|
+
logger: options.logger
|
|
22
|
+
});
|
|
23
|
+
options.rootLifecycle?.addShutdownHook(() => abortController.abort());
|
|
24
|
+
janitor.start(abortController.signal);
|
|
25
|
+
}
|
|
26
|
+
return knex;
|
|
27
|
+
});
|
|
28
|
+
return new PluginTaskSchedulerImpl.PluginTaskSchedulerImpl(
|
|
29
|
+
databaseFactory,
|
|
30
|
+
options.logger,
|
|
31
|
+
options.rootLifecycle
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
exports.DefaultSchedulerService = DefaultSchedulerService;
|
|
37
|
+
//# sourceMappingURL=DefaultSchedulerService.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultSchedulerService.cjs.js","sources":["../../../../src/entrypoints/scheduler/lib/DefaultSchedulerService.ts"],"sourcesContent":["/*\n * Copyright 2021 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 {\n DatabaseService,\n LoggerService,\n RootLifecycleService,\n SchedulerService,\n} from '@backstage/backend-plugin-api';\nimport { once } from 'lodash';\nimport { Duration } from 'luxon';\nimport { migrateBackendTasks } from '../database/migrateBackendTasks';\nimport { PluginTaskSchedulerImpl } from './PluginTaskSchedulerImpl';\nimport { PluginTaskSchedulerJanitor } from './PluginTaskSchedulerJanitor';\n\n/**\n * Default implementation of the task scheduler service.\n *\n * @public\n */\nexport class DefaultSchedulerService {\n static create(options: {\n database: DatabaseService;\n logger: LoggerService;\n rootLifecycle?: RootLifecycleService;\n }): SchedulerService {\n const databaseFactory = once(async () => {\n const knex = await options.database.getClient();\n\n if (!options.database.migrations?.skip) {\n await migrateBackendTasks(knex);\n }\n\n if (process.env.NODE_ENV !== 'test') {\n const abortController = new AbortController();\n const janitor = new PluginTaskSchedulerJanitor({\n knex,\n waitBetweenRuns: Duration.fromObject({ minutes: 1 }),\n logger: options.logger,\n });\n\n options.rootLifecycle?.addShutdownHook(() => abortController.abort());\n janitor.start(abortController.signal);\n }\n\n return knex;\n });\n\n return new PluginTaskSchedulerImpl(\n databaseFactory,\n options.logger,\n options.rootLifecycle,\n );\n }\n}\n"],"names":["once","migrateBackendTasks","PluginTaskSchedulerJanitor","Duration","PluginTaskSchedulerImpl"],"mappings":";;;;;;;;AAiCO,MAAM,uBAAwB,CAAA;AAAA,EACnC,OAAO,OAAO,OAIO,EAAA;AACnB,IAAM,MAAA,eAAA,GAAkBA,YAAK,YAAY;AACvC,MAAA,MAAM,IAAO,GAAA,MAAM,OAAQ,CAAA,QAAA,CAAS,SAAU,EAAA,CAAA;AAE9C,MAAA,IAAI,CAAC,OAAA,CAAQ,QAAS,CAAA,UAAA,EAAY,IAAM,EAAA;AACtC,QAAA,MAAMC,wCAAoB,IAAI,CAAA,CAAA;AAAA,OAChC;AAEA,MAAI,IAAA,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,MAAQ,EAAA;AACnC,QAAM,MAAA,eAAA,GAAkB,IAAI,eAAgB,EAAA,CAAA;AAC5C,QAAM,MAAA,OAAA,GAAU,IAAIC,qDAA2B,CAAA;AAAA,UAC7C,IAAA;AAAA,UACA,iBAAiBC,cAAS,CAAA,UAAA,CAAW,EAAE,OAAA,EAAS,GAAG,CAAA;AAAA,UACnD,QAAQ,OAAQ,CAAA,MAAA;AAAA,SACjB,CAAA,CAAA;AAED,QAAA,OAAA,CAAQ,aAAe,EAAA,eAAA,CAAgB,MAAM,eAAA,CAAgB,OAAO,CAAA,CAAA;AACpE,QAAQ,OAAA,CAAA,KAAA,CAAM,gBAAgB,MAAM,CAAA,CAAA;AAAA,OACtC;AAEA,MAAO,OAAA,IAAA,CAAA;AAAA,KACR,CAAA,CAAA;AAED,IAAA,OAAO,IAAIC,+CAAA;AAAA,MACT,eAAA;AAAA,MACA,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,aAAA;AAAA,KACV,CAAA;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var errors = require('@backstage/errors');
|
|
4
|
+
var cron = require('cron');
|
|
5
|
+
var luxon = require('luxon');
|
|
6
|
+
var util = require('./util.cjs.js');
|
|
7
|
+
|
|
8
|
+
class LocalTaskWorker {
|
|
9
|
+
constructor(taskId, fn, logger) {
|
|
10
|
+
this.taskId = taskId;
|
|
11
|
+
this.fn = fn;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
abortWait;
|
|
15
|
+
start(settings, options) {
|
|
16
|
+
this.logger.info(
|
|
17
|
+
`Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`
|
|
18
|
+
);
|
|
19
|
+
(async () => {
|
|
20
|
+
let attemptNum = 1;
|
|
21
|
+
for (; ; ) {
|
|
22
|
+
try {
|
|
23
|
+
if (settings.initialDelayDuration) {
|
|
24
|
+
await this.sleep(
|
|
25
|
+
luxon.Duration.fromISO(settings.initialDelayDuration),
|
|
26
|
+
options.signal
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
while (!options.signal.aborted) {
|
|
30
|
+
const startTime = process.hrtime();
|
|
31
|
+
await this.runOnce(settings, options.signal);
|
|
32
|
+
const timeTaken = process.hrtime(startTime);
|
|
33
|
+
await this.waitUntilNext(
|
|
34
|
+
settings,
|
|
35
|
+
(timeTaken[0] + timeTaken[1] / 1e9) * 1e3,
|
|
36
|
+
options.signal
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
this.logger.info(`Task worker finished: ${this.taskId}`);
|
|
40
|
+
attemptNum = 0;
|
|
41
|
+
break;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
attemptNum += 1;
|
|
44
|
+
this.logger.warn(
|
|
45
|
+
`Task worker failed unexpectedly, attempt number ${attemptNum}, ${e}`
|
|
46
|
+
);
|
|
47
|
+
await util.sleep(luxon.Duration.fromObject({ seconds: 1 }));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})();
|
|
51
|
+
}
|
|
52
|
+
trigger() {
|
|
53
|
+
if (!this.abortWait) {
|
|
54
|
+
throw new errors.ConflictError(`Task ${this.taskId} is currently running`);
|
|
55
|
+
}
|
|
56
|
+
this.abortWait.abort();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Makes a single attempt at running the task to completion.
|
|
60
|
+
*/
|
|
61
|
+
async runOnce(settings, signal) {
|
|
62
|
+
const taskAbortController = util.delegateAbortController(signal);
|
|
63
|
+
const timeoutHandle = setTimeout(() => {
|
|
64
|
+
taskAbortController.abort();
|
|
65
|
+
}, luxon.Duration.fromISO(settings.timeoutAfterDuration).as("milliseconds"));
|
|
66
|
+
try {
|
|
67
|
+
await this.fn(taskAbortController.signal);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
}
|
|
70
|
+
clearTimeout(timeoutHandle);
|
|
71
|
+
taskAbortController.abort();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Sleeps until it's time to run the task again.
|
|
75
|
+
*/
|
|
76
|
+
async waitUntilNext(settings, lastRunMillis, signal) {
|
|
77
|
+
if (signal.aborted) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const isCron = !settings.cadence.startsWith("P");
|
|
81
|
+
let dt;
|
|
82
|
+
if (isCron) {
|
|
83
|
+
const nextRun = +new cron.CronTime(settings.cadence).sendAt().toJSDate();
|
|
84
|
+
dt = nextRun - Date.now();
|
|
85
|
+
} else {
|
|
86
|
+
dt = luxon.Duration.fromISO(settings.cadence).as("milliseconds") - lastRunMillis;
|
|
87
|
+
}
|
|
88
|
+
dt = Math.max(dt, 0);
|
|
89
|
+
this.logger.debug(
|
|
90
|
+
`task: ${this.taskId} will next occur around ${luxon.DateTime.now().plus(
|
|
91
|
+
luxon.Duration.fromMillis(dt)
|
|
92
|
+
)}`
|
|
93
|
+
);
|
|
94
|
+
await this.sleep(luxon.Duration.fromMillis(dt), signal);
|
|
95
|
+
}
|
|
96
|
+
async sleep(duration, abortSignal) {
|
|
97
|
+
this.abortWait = util.delegateAbortController(abortSignal);
|
|
98
|
+
await util.sleep(duration, this.abortWait.signal);
|
|
99
|
+
this.abortWait.abort();
|
|
100
|
+
this.abortWait = void 0;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
exports.LocalTaskWorker = LocalTaskWorker;
|
|
105
|
+
//# sourceMappingURL=LocalTaskWorker.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalTaskWorker.cjs.js","sources":["../../../../src/entrypoints/scheduler/lib/LocalTaskWorker.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 { LoggerService } from '@backstage/backend-plugin-api';\nimport { SchedulerServiceTaskFunction } from '@backstage/backend-plugin-api';\nimport { ConflictError } from '@backstage/errors';\nimport { CronTime } from 'cron';\nimport { DateTime, Duration } from 'luxon';\nimport { TaskSettingsV2 } from './types';\nimport { delegateAbortController, sleep } from './util';\n\n/**\n * Implements tasks that run locally without cross-host collaboration.\n *\n * @private\n */\nexport class LocalTaskWorker {\n private abortWait: AbortController | undefined;\n\n constructor(\n private readonly taskId: string,\n private readonly fn: SchedulerServiceTaskFunction,\n private readonly logger: LoggerService,\n ) {}\n\n start(settings: TaskSettingsV2, options: { signal: AbortSignal }) {\n this.logger.info(\n `Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`,\n );\n\n (async () => {\n let attemptNum = 1;\n for (;;) {\n try {\n if (settings.initialDelayDuration) {\n await this.sleep(\n Duration.fromISO(settings.initialDelayDuration),\n options.signal,\n );\n }\n\n while (!options.signal.aborted) {\n const startTime = process.hrtime();\n await this.runOnce(settings, options.signal);\n const timeTaken = process.hrtime(startTime);\n await this.waitUntilNext(\n settings,\n (timeTaken[0] + timeTaken[1] / 1e9) * 1000,\n options.signal,\n );\n }\n\n this.logger.info(`Task worker finished: ${this.taskId}`);\n attemptNum = 0;\n break;\n } catch (e) {\n attemptNum += 1;\n this.logger.warn(\n `Task worker failed unexpectedly, attempt number ${attemptNum}, ${e}`,\n );\n await sleep(Duration.fromObject({ seconds: 1 }));\n }\n }\n })();\n }\n\n trigger(): void {\n if (!this.abortWait) {\n throw new ConflictError(`Task ${this.taskId} is currently running`);\n }\n this.abortWait.abort();\n }\n\n /**\n * Makes a single attempt at running the task to completion.\n */\n private async runOnce(\n settings: TaskSettingsV2,\n signal: AbortSignal,\n ): Promise<void> {\n // Abort the task execution either if the worker is stopped, or if the\n // task timeout is hit\n const taskAbortController = delegateAbortController(signal);\n const timeoutHandle = setTimeout(() => {\n taskAbortController.abort();\n }, Duration.fromISO(settings.timeoutAfterDuration).as('milliseconds'));\n\n try {\n await this.fn(taskAbortController.signal);\n } catch (e) {\n // ignore intentionally\n }\n\n // release resources\n clearTimeout(timeoutHandle);\n taskAbortController.abort();\n }\n\n /**\n * Sleeps until it's time to run the task again.\n */\n private async waitUntilNext(\n settings: TaskSettingsV2,\n lastRunMillis: number,\n signal: AbortSignal,\n ) {\n if (signal.aborted) {\n return;\n }\n\n const isCron = !settings.cadence.startsWith('P');\n let dt: number;\n\n if (isCron) {\n const nextRun = +new CronTime(settings.cadence).sendAt().toJSDate();\n dt = nextRun - Date.now();\n } else {\n dt =\n Duration.fromISO(settings.cadence).as('milliseconds') - lastRunMillis;\n }\n\n dt = Math.max(dt, 0);\n\n this.logger.debug(\n `task: ${this.taskId} will next occur around ${DateTime.now().plus(\n Duration.fromMillis(dt),\n )}`,\n );\n\n await this.sleep(Duration.fromMillis(dt), signal);\n }\n\n private async sleep(\n duration: Duration,\n abortSignal: AbortSignal,\n ): Promise<void> {\n this.abortWait = delegateAbortController(abortSignal);\n await sleep(duration, this.abortWait.signal);\n this.abortWait.abort(); // cleans up resources\n this.abortWait = undefined;\n }\n}\n"],"names":["Duration","sleep","ConflictError","delegateAbortController","CronTime","DateTime"],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var api = require('@opentelemetry/api');
|
|
4
|
+
var luxon = require('luxon');
|
|
5
|
+
var LocalTaskWorker = require('./LocalTaskWorker.cjs.js');
|
|
6
|
+
var TaskWorker = require('./TaskWorker.cjs.js');
|
|
7
|
+
var util = require('./util.cjs.js');
|
|
8
|
+
|
|
9
|
+
const tracer = api.trace.getTracer(util.TRACER_ID);
|
|
10
|
+
class PluginTaskSchedulerImpl {
|
|
11
|
+
constructor(databaseFactory, logger, rootLifecycle) {
|
|
12
|
+
this.databaseFactory = databaseFactory;
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
const meter = api.metrics.getMeter("default");
|
|
15
|
+
this.counter = meter.createCounter("backend_tasks.task.runs.count", {
|
|
16
|
+
description: "Total number of times a task has been run"
|
|
17
|
+
});
|
|
18
|
+
this.duration = meter.createHistogram("backend_tasks.task.runs.duration", {
|
|
19
|
+
description: "Histogram of task run durations",
|
|
20
|
+
unit: "seconds"
|
|
21
|
+
});
|
|
22
|
+
this.shutdownInitiated = new Promise((shutdownInitiated) => {
|
|
23
|
+
rootLifecycle?.addShutdownHook(() => shutdownInitiated(true));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
localTasksById = /* @__PURE__ */ new Map();
|
|
27
|
+
allScheduledTasks = [];
|
|
28
|
+
shutdownInitiated;
|
|
29
|
+
counter;
|
|
30
|
+
duration;
|
|
31
|
+
async triggerTask(id) {
|
|
32
|
+
const localTask = this.localTasksById.get(id);
|
|
33
|
+
if (localTask) {
|
|
34
|
+
localTask.trigger();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const knex = await this.databaseFactory();
|
|
38
|
+
await TaskWorker.TaskWorker.trigger(knex, id);
|
|
39
|
+
}
|
|
40
|
+
async scheduleTask(task) {
|
|
41
|
+
util.validateId(task.id);
|
|
42
|
+
const scope = task.scope ?? "global";
|
|
43
|
+
const settings = {
|
|
44
|
+
version: 2,
|
|
45
|
+
cadence: parseDuration(task.frequency),
|
|
46
|
+
initialDelayDuration: task.initialDelay && parseDuration(task.initialDelay),
|
|
47
|
+
timeoutAfterDuration: parseDuration(task.timeout)
|
|
48
|
+
};
|
|
49
|
+
const abortController = util.delegateAbortController(task.signal);
|
|
50
|
+
this.shutdownInitiated.then(() => abortController.abort());
|
|
51
|
+
if (scope === "global") {
|
|
52
|
+
const knex = await this.databaseFactory();
|
|
53
|
+
const worker = new TaskWorker.TaskWorker(
|
|
54
|
+
task.id,
|
|
55
|
+
this.instrumentedFunction(task, scope),
|
|
56
|
+
knex,
|
|
57
|
+
this.logger.child({ task: task.id })
|
|
58
|
+
);
|
|
59
|
+
await worker.start(settings, { signal: abortController.signal });
|
|
60
|
+
} else {
|
|
61
|
+
const worker = new LocalTaskWorker.LocalTaskWorker(
|
|
62
|
+
task.id,
|
|
63
|
+
this.instrumentedFunction(task, scope),
|
|
64
|
+
this.logger.child({ task: task.id })
|
|
65
|
+
);
|
|
66
|
+
worker.start(settings, { signal: abortController.signal });
|
|
67
|
+
this.localTasksById.set(task.id, worker);
|
|
68
|
+
}
|
|
69
|
+
this.allScheduledTasks.push({
|
|
70
|
+
id: task.id,
|
|
71
|
+
scope,
|
|
72
|
+
settings
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
createScheduledTaskRunner(schedule) {
|
|
76
|
+
return {
|
|
77
|
+
run: async (task) => {
|
|
78
|
+
await this.scheduleTask({ ...task, ...schedule });
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async getScheduledTasks() {
|
|
83
|
+
return this.allScheduledTasks;
|
|
84
|
+
}
|
|
85
|
+
instrumentedFunction(task, scope) {
|
|
86
|
+
return async (abort) => {
|
|
87
|
+
const labels = {
|
|
88
|
+
taskId: task.id,
|
|
89
|
+
scope
|
|
90
|
+
};
|
|
91
|
+
this.counter.add(1, { ...labels, result: "started" });
|
|
92
|
+
const startTime = process.hrtime();
|
|
93
|
+
try {
|
|
94
|
+
await tracer.startActiveSpan(`task ${task.id}`, async (span) => {
|
|
95
|
+
try {
|
|
96
|
+
span.setAttributes(labels);
|
|
97
|
+
await task.fn(abort);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
if (error instanceof Error) {
|
|
100
|
+
span.recordException(error);
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
} finally {
|
|
104
|
+
span.end();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
labels.result = "completed";
|
|
108
|
+
} catch (ex) {
|
|
109
|
+
labels.result = "failed";
|
|
110
|
+
throw ex;
|
|
111
|
+
} finally {
|
|
112
|
+
const delta = process.hrtime(startTime);
|
|
113
|
+
const endTime = delta[0] + delta[1] / 1e9;
|
|
114
|
+
this.counter.add(1, labels);
|
|
115
|
+
this.duration.record(endTime, labels);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function parseDuration(frequency) {
|
|
121
|
+
if (typeof frequency === "object" && "cron" in frequency) {
|
|
122
|
+
return frequency.cron;
|
|
123
|
+
}
|
|
124
|
+
if (typeof frequency === "object" && "trigger" in frequency) {
|
|
125
|
+
return frequency.trigger;
|
|
126
|
+
}
|
|
127
|
+
const parsed = luxon.Duration.isDuration(frequency) ? frequency : luxon.Duration.fromObject(frequency);
|
|
128
|
+
if (!parsed.isValid) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Invalid duration, ${parsed.invalidReason}: ${parsed.invalidExplanation}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
return parsed.toISO();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
exports.PluginTaskSchedulerImpl = PluginTaskSchedulerImpl;
|
|
137
|
+
exports.parseDuration = parseDuration;
|
|
138
|
+
//# sourceMappingURL=PluginTaskSchedulerImpl.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginTaskSchedulerImpl.cjs.js","sources":["../../../../src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts"],"sourcesContent":["/*\n * Copyright 2021 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 {\n LoggerService,\n RootLifecycleService,\n SchedulerService,\n SchedulerServiceTaskDescriptor,\n SchedulerServiceTaskFunction,\n SchedulerServiceTaskInvocationDefinition,\n SchedulerServiceTaskRunner,\n SchedulerServiceTaskScheduleDefinition,\n} from '@backstage/backend-plugin-api';\nimport { Counter, Histogram, metrics, trace } from '@opentelemetry/api';\nimport { Knex } from 'knex';\nimport { Duration } from 'luxon';\nimport { LocalTaskWorker } from './LocalTaskWorker';\nimport { TaskWorker } from './TaskWorker';\nimport { TaskSettingsV2 } from './types';\nimport { delegateAbortController, TRACER_ID, validateId } from './util';\n\nconst tracer = trace.getTracer(TRACER_ID);\n\n/**\n * Implements the actual task management.\n */\nexport class PluginTaskSchedulerImpl implements SchedulerService {\n private readonly localTasksById = new Map<string, LocalTaskWorker>();\n private readonly allScheduledTasks: SchedulerServiceTaskDescriptor[] = [];\n private readonly shutdownInitiated: Promise<boolean>;\n\n private readonly counter: Counter;\n private readonly duration: Histogram;\n\n constructor(\n private readonly databaseFactory: () => Promise<Knex>,\n private readonly logger: LoggerService,\n rootLifecycle?: RootLifecycleService,\n ) {\n const meter = metrics.getMeter('default');\n this.counter = meter.createCounter('backend_tasks.task.runs.count', {\n description: 'Total number of times a task has been run',\n });\n this.duration = meter.createHistogram('backend_tasks.task.runs.duration', {\n description: 'Histogram of task run durations',\n unit: 'seconds',\n });\n this.shutdownInitiated = new Promise(shutdownInitiated => {\n rootLifecycle?.addShutdownHook(() => shutdownInitiated(true));\n });\n }\n\n async triggerTask(id: string): Promise<void> {\n const localTask = this.localTasksById.get(id);\n if (localTask) {\n localTask.trigger();\n return;\n }\n\n const knex = await this.databaseFactory();\n await TaskWorker.trigger(knex, id);\n }\n\n async scheduleTask(\n task: SchedulerServiceTaskScheduleDefinition &\n SchedulerServiceTaskInvocationDefinition,\n ): Promise<void> {\n validateId(task.id);\n const scope = task.scope ?? 'global';\n\n const settings: TaskSettingsV2 = {\n version: 2,\n cadence: parseDuration(task.frequency),\n initialDelayDuration:\n task.initialDelay && parseDuration(task.initialDelay),\n timeoutAfterDuration: parseDuration(task.timeout),\n };\n\n // Delegated abort controller that will abort either when the provided\n // controller aborts, or when a root lifecycle shutdown happens\n const abortController = delegateAbortController(task.signal);\n this.shutdownInitiated.then(() => abortController.abort());\n\n if (scope === 'global') {\n const knex = await this.databaseFactory();\n const worker = new TaskWorker(\n task.id,\n this.instrumentedFunction(task, scope),\n knex,\n this.logger.child({ task: task.id }),\n );\n await worker.start(settings, { signal: abortController.signal });\n } else {\n const worker = new LocalTaskWorker(\n task.id,\n this.instrumentedFunction(task, scope),\n this.logger.child({ task: task.id }),\n );\n worker.start(settings, { signal: abortController.signal });\n this.localTasksById.set(task.id, worker);\n }\n\n this.allScheduledTasks.push({\n id: task.id,\n scope: scope,\n settings: settings,\n });\n }\n\n createScheduledTaskRunner(\n schedule: SchedulerServiceTaskScheduleDefinition,\n ): SchedulerServiceTaskRunner {\n return {\n run: async task => {\n await this.scheduleTask({ ...task, ...schedule });\n },\n };\n }\n\n async getScheduledTasks(): Promise<SchedulerServiceTaskDescriptor[]> {\n return this.allScheduledTasks;\n }\n\n private instrumentedFunction(\n task: SchedulerServiceTaskInvocationDefinition,\n scope: string,\n ): SchedulerServiceTaskFunction {\n return async abort => {\n const labels: Record<string, string> = {\n taskId: task.id,\n scope,\n };\n this.counter.add(1, { ...labels, result: 'started' });\n\n const startTime = process.hrtime();\n\n try {\n await tracer.startActiveSpan(`task ${task.id}`, async span => {\n try {\n span.setAttributes(labels);\n await task.fn(abort);\n } catch (error) {\n if (error instanceof Error) {\n span.recordException(error);\n }\n throw error;\n } finally {\n span.end();\n }\n });\n labels.result = 'completed';\n } catch (ex) {\n labels.result = 'failed';\n throw ex;\n } finally {\n const delta = process.hrtime(startTime);\n const endTime = delta[0] + delta[1] / 1e9;\n this.counter.add(1, labels);\n this.duration.record(endTime, labels);\n }\n };\n }\n}\n\nexport function parseDuration(\n frequency: SchedulerServiceTaskScheduleDefinition['frequency'],\n): string {\n if (typeof frequency === 'object' && 'cron' in frequency) {\n return frequency.cron;\n }\n if (typeof frequency === 'object' && 'trigger' in frequency) {\n return frequency.trigger;\n }\n\n const parsed = Duration.isDuration(frequency)\n ? frequency\n : Duration.fromObject(frequency);\n\n if (!parsed.isValid) {\n throw new Error(\n `Invalid duration, ${parsed.invalidReason}: ${parsed.invalidExplanation}`,\n );\n }\n\n return parsed.toISO()!;\n}\n"],"names":["trace","TRACER_ID","metrics","TaskWorker","validateId","delegateAbortController","LocalTaskWorker","Duration"],"mappings":";;;;;;;;AAkCA,MAAM,MAAA,GAASA,SAAM,CAAA,SAAA,CAAUC,cAAS,CAAA,CAAA;AAKjC,MAAM,uBAAoD,CAAA;AAAA,EAQ/D,WAAA,CACmB,eACA,EAAA,MAAA,EACjB,aACA,EAAA;AAHiB,IAAA,IAAA,CAAA,eAAA,GAAA,eAAA,CAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA,CAAA;AAGjB,IAAM,MAAA,KAAA,GAAQC,WAAQ,CAAA,QAAA,CAAS,SAAS,CAAA,CAAA;AACxC,IAAK,IAAA,CAAA,OAAA,GAAU,KAAM,CAAA,aAAA,CAAc,+BAAiC,EAAA;AAAA,MAClE,WAAa,EAAA,2CAAA;AAAA,KACd,CAAA,CAAA;AACD,IAAK,IAAA,CAAA,QAAA,GAAW,KAAM,CAAA,eAAA,CAAgB,kCAAoC,EAAA;AAAA,MACxE,WAAa,EAAA,iCAAA;AAAA,MACb,IAAM,EAAA,SAAA;AAAA,KACP,CAAA,CAAA;AACD,IAAK,IAAA,CAAA,iBAAA,GAAoB,IAAI,OAAA,CAAQ,CAAqB,iBAAA,KAAA;AACxD,MAAA,aAAA,EAAe,eAAgB,CAAA,MAAM,iBAAkB,CAAA,IAAI,CAAC,CAAA,CAAA;AAAA,KAC7D,CAAA,CAAA;AAAA,GACH;AAAA,EAvBiB,cAAA,uBAAqB,GAA6B,EAAA,CAAA;AAAA,EAClD,oBAAsD,EAAC,CAAA;AAAA,EACvD,iBAAA,CAAA;AAAA,EAEA,OAAA,CAAA;AAAA,EACA,QAAA,CAAA;AAAA,EAoBjB,MAAM,YAAY,EAA2B,EAAA;AAC3C,IAAA,MAAM,SAAY,GAAA,IAAA,CAAK,cAAe,CAAA,GAAA,CAAI,EAAE,CAAA,CAAA;AAC5C,IAAA,IAAI,SAAW,EAAA;AACb,MAAA,SAAA,CAAU,OAAQ,EAAA,CAAA;AAClB,MAAA,OAAA;AAAA,KACF;AAEA,IAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,eAAgB,EAAA,CAAA;AACxC,IAAM,MAAAC,qBAAA,CAAW,OAAQ,CAAA,IAAA,EAAM,EAAE,CAAA,CAAA;AAAA,GACnC;AAAA,EAEA,MAAM,aACJ,IAEe,EAAA;AACf,IAAAC,eAAA,CAAW,KAAK,EAAE,CAAA,CAAA;AAClB,IAAM,MAAA,KAAA,GAAQ,KAAK,KAAS,IAAA,QAAA,CAAA;AAE5B,IAAA,MAAM,QAA2B,GAAA;AAAA,MAC/B,OAAS,EAAA,CAAA;AAAA,MACT,OAAA,EAAS,aAAc,CAAA,IAAA,CAAK,SAAS,CAAA;AAAA,MACrC,oBACE,EAAA,IAAA,CAAK,YAAgB,IAAA,aAAA,CAAc,KAAK,YAAY,CAAA;AAAA,MACtD,oBAAA,EAAsB,aAAc,CAAA,IAAA,CAAK,OAAO,CAAA;AAAA,KAClD,CAAA;AAIA,IAAM,MAAA,eAAA,GAAkBC,4BAAwB,CAAA,IAAA,CAAK,MAAM,CAAA,CAAA;AAC3D,IAAA,IAAA,CAAK,iBAAkB,CAAA,IAAA,CAAK,MAAM,eAAA,CAAgB,OAAO,CAAA,CAAA;AAEzD,IAAA,IAAI,UAAU,QAAU,EAAA;AACtB,MAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,eAAgB,EAAA,CAAA;AACxC,MAAA,MAAM,SAAS,IAAIF,qBAAA;AAAA,QACjB,IAAK,CAAA,EAAA;AAAA,QACL,IAAA,CAAK,oBAAqB,CAAA,IAAA,EAAM,KAAK,CAAA;AAAA,QACrC,IAAA;AAAA,QACA,KAAK,MAAO,CAAA,KAAA,CAAM,EAAE,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,OACrC,CAAA;AACA,MAAA,MAAM,OAAO,KAAM,CAAA,QAAA,EAAU,EAAE,MAAQ,EAAA,eAAA,CAAgB,QAAQ,CAAA,CAAA;AAAA,KAC1D,MAAA;AACL,MAAA,MAAM,SAAS,IAAIG,+BAAA;AAAA,QACjB,IAAK,CAAA,EAAA;AAAA,QACL,IAAA,CAAK,oBAAqB,CAAA,IAAA,EAAM,KAAK,CAAA;AAAA,QACrC,KAAK,MAAO,CAAA,KAAA,CAAM,EAAE,IAAM,EAAA,IAAA,CAAK,IAAI,CAAA;AAAA,OACrC,CAAA;AACA,MAAA,MAAA,CAAO,MAAM,QAAU,EAAA,EAAE,MAAQ,EAAA,eAAA,CAAgB,QAAQ,CAAA,CAAA;AACzD,MAAA,IAAA,CAAK,cAAe,CAAA,GAAA,CAAI,IAAK,CAAA,EAAA,EAAI,MAAM,CAAA,CAAA;AAAA,KACzC;AAEA,IAAA,IAAA,CAAK,kBAAkB,IAAK,CAAA;AAAA,MAC1B,IAAI,IAAK,CAAA,EAAA;AAAA,MACT,KAAA;AAAA,MACA,QAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,0BACE,QAC4B,EAAA;AAC5B,IAAO,OAAA;AAAA,MACL,GAAA,EAAK,OAAM,IAAQ,KAAA;AACjB,QAAA,MAAM,KAAK,YAAa,CAAA,EAAE,GAAG,IAAM,EAAA,GAAG,UAAU,CAAA,CAAA;AAAA,OAClD;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,MAAM,iBAA+D,GAAA;AACnE,IAAA,OAAO,IAAK,CAAA,iBAAA,CAAA;AAAA,GACd;AAAA,EAEQ,oBAAA,CACN,MACA,KAC8B,EAAA;AAC9B,IAAA,OAAO,OAAM,KAAS,KAAA;AACpB,MAAA,MAAM,MAAiC,GAAA;AAAA,QACrC,QAAQ,IAAK,CAAA,EAAA;AAAA,QACb,KAAA;AAAA,OACF,CAAA;AACA,MAAK,IAAA,CAAA,OAAA,CAAQ,IAAI,CAAG,EAAA,EAAE,GAAG,MAAQ,EAAA,MAAA,EAAQ,WAAW,CAAA,CAAA;AAEpD,MAAM,MAAA,SAAA,GAAY,QAAQ,MAAO,EAAA,CAAA;AAEjC,MAAI,IAAA;AACF,QAAA,MAAM,OAAO,eAAgB,CAAA,CAAA,KAAA,EAAQ,KAAK,EAAE,CAAA,CAAA,EAAI,OAAM,IAAQ,KAAA;AAC5D,UAAI,IAAA;AACF,YAAA,IAAA,CAAK,cAAc,MAAM,CAAA,CAAA;AACzB,YAAM,MAAA,IAAA,CAAK,GAAG,KAAK,CAAA,CAAA;AAAA,mBACZ,KAAO,EAAA;AACd,YAAA,IAAI,iBAAiB,KAAO,EAAA;AAC1B,cAAA,IAAA,CAAK,gBAAgB,KAAK,CAAA,CAAA;AAAA,aAC5B;AACA,YAAM,MAAA,KAAA,CAAA;AAAA,WACN,SAAA;AACA,YAAA,IAAA,CAAK,GAAI,EAAA,CAAA;AAAA,WACX;AAAA,SACD,CAAA,CAAA;AACD,QAAA,MAAA,CAAO,MAAS,GAAA,WAAA,CAAA;AAAA,eACT,EAAI,EAAA;AACX,QAAA,MAAA,CAAO,MAAS,GAAA,QAAA,CAAA;AAChB,QAAM,MAAA,EAAA,CAAA;AAAA,OACN,SAAA;AACA,QAAM,MAAA,KAAA,GAAQ,OAAQ,CAAA,MAAA,CAAO,SAAS,CAAA,CAAA;AACtC,QAAA,MAAM,UAAU,KAAM,CAAA,CAAC,CAAI,GAAA,KAAA,CAAM,CAAC,CAAI,GAAA,GAAA,CAAA;AACtC,QAAK,IAAA,CAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,EAAG,MAAM,CAAA,CAAA;AAC1B,QAAK,IAAA,CAAA,QAAA,CAAS,MAAO,CAAA,OAAA,EAAS,MAAM,CAAA,CAAA;AAAA,OACtC;AAAA,KACF,CAAA;AAAA,GACF;AACF,CAAA;AAEO,SAAS,cACd,SACQ,EAAA;AACR,EAAA,IAAI,OAAO,SAAA,KAAc,QAAY,IAAA,MAAA,IAAU,SAAW,EAAA;AACxD,IAAA,OAAO,SAAU,CAAA,IAAA,CAAA;AAAA,GACnB;AACA,EAAA,IAAI,OAAO,SAAA,KAAc,QAAY,IAAA,SAAA,IAAa,SAAW,EAAA;AAC3D,IAAA,OAAO,SAAU,CAAA,OAAA,CAAA;AAAA,GACnB;AAEA,EAAM,MAAA,MAAA,GAASC,eAAS,UAAW,CAAA,SAAS,IACxC,SACA,GAAAA,cAAA,CAAS,WAAW,SAAS,CAAA,CAAA;AAEjC,EAAI,IAAA,CAAC,OAAO,OAAS,EAAA;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAqB,kBAAA,EAAA,MAAA,CAAO,aAAa,CAAA,EAAA,EAAK,OAAO,kBAAkB,CAAA,CAAA;AAAA,KACzE,CAAA;AAAA,GACF;AAEA,EAAA,OAAO,OAAO,KAAM,EAAA,CAAA;AACtB;;;;;"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tables = require('../database/tables.cjs.js');
|
|
4
|
+
var util = require('./util.cjs.js');
|
|
5
|
+
|
|
6
|
+
class PluginTaskSchedulerJanitor {
|
|
7
|
+
knex;
|
|
8
|
+
waitBetweenRuns;
|
|
9
|
+
logger;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.knex = options.knex;
|
|
12
|
+
this.waitBetweenRuns = options.waitBetweenRuns;
|
|
13
|
+
this.logger = options.logger;
|
|
14
|
+
}
|
|
15
|
+
async start(abortSignal) {
|
|
16
|
+
while (!abortSignal?.aborted) {
|
|
17
|
+
try {
|
|
18
|
+
await this.runOnce();
|
|
19
|
+
} catch (e) {
|
|
20
|
+
this.logger.warn(`Error while performing janitorial tasks, ${e}`);
|
|
21
|
+
}
|
|
22
|
+
await util.sleep(this.waitBetweenRuns, abortSignal);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async runOnce() {
|
|
26
|
+
const dbNull = this.knex.raw("null");
|
|
27
|
+
const configClient = this.knex.client.config.client;
|
|
28
|
+
let tasks;
|
|
29
|
+
if (configClient.includes("sqlite3") || configClient.includes("mysql")) {
|
|
30
|
+
tasks = await this.knex(tables.DB_TASKS_TABLE).select("id").where("current_run_expires_at", "<", this.knex.fn.now());
|
|
31
|
+
await this.knex(tables.DB_TASKS_TABLE).whereIn(
|
|
32
|
+
"id",
|
|
33
|
+
tasks.map((t) => t.id)
|
|
34
|
+
).update({
|
|
35
|
+
current_run_ticket: dbNull,
|
|
36
|
+
current_run_started_at: dbNull,
|
|
37
|
+
current_run_expires_at: dbNull
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
tasks = await this.knex(tables.DB_TASKS_TABLE).where("current_run_expires_at", "<", this.knex.fn.now()).update({
|
|
41
|
+
current_run_ticket: dbNull,
|
|
42
|
+
current_run_started_at: dbNull,
|
|
43
|
+
current_run_expires_at: dbNull
|
|
44
|
+
}).returning(["id"]);
|
|
45
|
+
}
|
|
46
|
+
if (typeof tasks === "number") {
|
|
47
|
+
if (tasks > 0) {
|
|
48
|
+
this.logger.warn(`${tasks} tasks timed out and were lost`);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
for (const { id } of tasks) {
|
|
52
|
+
this.logger.warn(`Task timed out and was lost: ${id}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
exports.PluginTaskSchedulerJanitor = PluginTaskSchedulerJanitor;
|
|
59
|
+
//# sourceMappingURL=PluginTaskSchedulerJanitor.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginTaskSchedulerJanitor.cjs.js","sources":["../../../../src/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.ts"],"sourcesContent":["/*\n * Copyright 2021 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 { LoggerService } from '@backstage/backend-plugin-api';\nimport { Knex } from 'knex';\nimport { Duration } from 'luxon';\nimport { DB_TASKS_TABLE, DbTasksRow } from '../database/tables';\nimport { sleep } from './util';\n\n/**\n * Makes sure to auto-expire and clean up things that time out or for other\n * reasons should not be left lingering.\n */\nexport class PluginTaskSchedulerJanitor {\n private readonly knex: Knex;\n private readonly waitBetweenRuns: Duration;\n private readonly logger: LoggerService;\n\n constructor(options: {\n knex: Knex;\n waitBetweenRuns: Duration;\n logger: LoggerService;\n }) {\n this.knex = options.knex;\n this.waitBetweenRuns = options.waitBetweenRuns;\n this.logger = options.logger;\n }\n\n async start(abortSignal?: AbortSignal) {\n while (!abortSignal?.aborted) {\n try {\n await this.runOnce();\n } catch (e) {\n this.logger.warn(`Error while performing janitorial tasks, ${e}`);\n }\n\n await sleep(this.waitBetweenRuns, abortSignal);\n }\n }\n\n private async runOnce() {\n const dbNull = this.knex.raw('null');\n const configClient = this.knex.client.config.client;\n\n let tasks: Array<{ id: string }>;\n if (configClient.includes('sqlite3') || configClient.includes('mysql')) {\n tasks = await this.knex<DbTasksRow>(DB_TASKS_TABLE)\n .select('id')\n .where('current_run_expires_at', '<', this.knex.fn.now());\n await this.knex<DbTasksRow>(DB_TASKS_TABLE)\n .whereIn(\n 'id',\n tasks.map(t => t.id),\n )\n .update({\n current_run_ticket: dbNull,\n current_run_started_at: dbNull,\n current_run_expires_at: dbNull,\n });\n } else {\n tasks = await this.knex<DbTasksRow>(DB_TASKS_TABLE)\n .where('current_run_expires_at', '<', this.knex.fn.now())\n .update({\n current_run_ticket: dbNull,\n current_run_started_at: dbNull,\n current_run_expires_at: dbNull,\n })\n .returning(['id']);\n }\n\n // In rare cases, knex drivers may ignore \"returning\", and return the number\n // of rows changed instead\n if (typeof tasks === 'number') {\n if (tasks > 0) {\n this.logger.warn(`${tasks} tasks timed out and were lost`);\n }\n } else {\n for (const { id } of tasks) {\n this.logger.warn(`Task timed out and was lost: ${id}`);\n }\n }\n }\n}\n"],"names":["sleep","DB_TASKS_TABLE"],"mappings":";;;;;AA0BO,MAAM,0BAA2B,CAAA;AAAA,EACrB,IAAA,CAAA;AAAA,EACA,eAAA,CAAA;AAAA,EACA,MAAA,CAAA;AAAA,EAEjB,YAAY,OAIT,EAAA;AACD,IAAA,IAAA,CAAK,OAAO,OAAQ,CAAA,IAAA,CAAA;AACpB,IAAA,IAAA,CAAK,kBAAkB,OAAQ,CAAA,eAAA,CAAA;AAC/B,IAAA,IAAA,CAAK,SAAS,OAAQ,CAAA,MAAA,CAAA;AAAA,GACxB;AAAA,EAEA,MAAM,MAAM,WAA2B,EAAA;AACrC,IAAO,OAAA,CAAC,aAAa,OAAS,EAAA;AAC5B,MAAI,IAAA;AACF,QAAA,MAAM,KAAK,OAAQ,EAAA,CAAA;AAAA,eACZ,CAAG,EAAA;AACV,QAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAA4C,yCAAA,EAAA,CAAC,CAAE,CAAA,CAAA,CAAA;AAAA,OAClE;AAEA,MAAM,MAAAA,UAAA,CAAM,IAAK,CAAA,eAAA,EAAiB,WAAW,CAAA,CAAA;AAAA,KAC/C;AAAA,GACF;AAAA,EAEA,MAAc,OAAU,GAAA;AACtB,IAAA,MAAM,MAAS,GAAA,IAAA,CAAK,IAAK,CAAA,GAAA,CAAI,MAAM,CAAA,CAAA;AACnC,IAAA,MAAM,YAAe,GAAA,IAAA,CAAK,IAAK,CAAA,MAAA,CAAO,MAAO,CAAA,MAAA,CAAA;AAE7C,IAAI,IAAA,KAAA,CAAA;AACJ,IAAA,IAAI,aAAa,QAAS,CAAA,SAAS,KAAK,YAAa,CAAA,QAAA,CAAS,OAAO,CAAG,EAAA;AACtE,MAAA,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAiB,CAAAC,qBAAc,EAC/C,MAAO,CAAA,IAAI,CACX,CAAA,KAAA,CAAM,0BAA0B,GAAK,EAAA,IAAA,CAAK,IAAK,CAAA,EAAA,CAAG,KAAK,CAAA,CAAA;AAC1D,MAAM,MAAA,IAAA,CAAK,IAAiB,CAAAA,qBAAc,CACvC,CAAA,OAAA;AAAA,QACC,IAAA;AAAA,QACA,KAAM,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,EAAE,CAAA;AAAA,QAEpB,MAAO,CAAA;AAAA,QACN,kBAAoB,EAAA,MAAA;AAAA,QACpB,sBAAwB,EAAA,MAAA;AAAA,QACxB,sBAAwB,EAAA,MAAA;AAAA,OACzB,CAAA,CAAA;AAAA,KACE,MAAA;AACL,MAAA,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAiB,CAAAA,qBAAc,EAC/C,KAAM,CAAA,wBAAA,EAA0B,GAAK,EAAA,IAAA,CAAK,IAAK,CAAA,EAAA,CAAG,GAAI,EAAC,EACvD,MAAO,CAAA;AAAA,QACN,kBAAoB,EAAA,MAAA;AAAA,QACpB,sBAAwB,EAAA,MAAA;AAAA,QACxB,sBAAwB,EAAA,MAAA;AAAA,OACzB,CAAA,CACA,SAAU,CAAA,CAAC,IAAI,CAAC,CAAA,CAAA;AAAA,KACrB;AAIA,IAAI,IAAA,OAAO,UAAU,QAAU,EAAA;AAC7B,MAAA,IAAI,QAAQ,CAAG,EAAA;AACb,QAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAAG,EAAA,KAAK,CAAgC,8BAAA,CAAA,CAAA,CAAA;AAAA,OAC3D;AAAA,KACK,MAAA;AACL,MAAW,KAAA,MAAA,EAAE,EAAG,EAAA,IAAK,KAAO,EAAA;AAC1B,QAAA,IAAA,CAAK,MAAO,CAAA,IAAA,CAAK,CAAgC,6BAAA,EAAA,EAAE,CAAE,CAAA,CAAA,CAAA;AAAA,OACvD;AAAA,KACF;AAAA,GACF;AACF;;;;"}
|