@harperfast/harper 5.2.13 → 5.3.0-beta.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/agent/mcpTools.ts +1 -1
- package/agent/session.ts +25 -14
- package/bin/cliOperations.ts +58 -9
- package/bin/copyDb.ts +282 -59
- package/bin/deploySetup.ts +16 -5
- package/bin/harper.ts +1 -1
- package/bin/help.ts +4 -1
- package/bin/lite.ts +4 -1
- package/bin/restart.ts +120 -4
- package/bin/run.ts +6 -11
- package/bin/upgrade.js +7 -3
- package/bin/workloadIdentity.ts +119 -0
- package/components/Application.ts +3436 -242
- package/components/ApplicationScope.ts +8 -0
- package/components/EntryHandler.ts +59 -39
- package/components/OptionsWatcher.ts +440 -98
- package/components/RuntimeModuleTracker.ts +38 -7
- package/components/Scope.ts +56 -15
- package/components/awaitRestart.ts +84 -0
- package/components/componentLoader.ts +381 -32
- package/components/componentPreparationLock.ts +16 -5
- package/components/deploymentOperations.ts +4 -1
- package/components/deploymentRecorder.ts +9 -2
- package/components/mcp/adapters/harperHttp.ts +4 -0
- package/components/mcp/listChanged.ts +4 -0
- package/components/mcp/toolRegistry.ts +2 -0
- package/components/mcp/tools/operations.ts +9 -0
- package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
- package/components/operations.js +537 -113
- package/components/operationsValidation.js +98 -3
- package/components/packageComponent.ts +25 -1
- package/components/requestRestart.ts +11 -0
- package/components/status/ComponentStatusRegistry.ts +59 -0
- package/config/RootConfigWatcher.ts +240 -40
- package/config/configReadRetry.ts +62 -0
- package/config/configUtils.ts +357 -48
- package/config/harperConfigEnvVars.ts +170 -27
- package/config/parseConfigFile.ts +34 -0
- package/config/readConfigFileSync.ts +44 -0
- package/config/watcherArming.ts +59 -0
- package/config-root.schema.json +33 -0
- package/dataLayer/blobBackup.ts +160 -50
- package/dataLayer/delete.ts +6 -1
- package/dataLayer/harperBridge/ResourceBridge.ts +80 -10
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dataLayer/hdbInfoController.ts +34 -1
- package/dataLayer/insert.ts +44 -1
- package/dataLayer/rocksdbBackup.ts +53 -10
- package/dataLayer/schema.ts +11 -1
- package/dataLayer/schemaDescribe.ts +8 -1
- package/dist/agent/mcpTools.js +1 -1
- package/dist/agent/mcpTools.js.map +1 -1
- package/dist/agent/session.d.ts +22 -0
- package/dist/agent/session.js +26 -15
- package/dist/agent/session.js.map +1 -1
- package/dist/bin/cliOperations.js +61 -9
- package/dist/bin/cliOperations.js.map +1 -1
- package/dist/bin/copyDb.d.ts +12 -1
- package/dist/bin/copyDb.js +248 -60
- package/dist/bin/copyDb.js.map +1 -1
- package/dist/bin/deploySetup.d.ts +2 -0
- package/dist/bin/deploySetup.js +11 -3
- package/dist/bin/deploySetup.js.map +1 -1
- package/dist/bin/harper.js +1 -1
- package/dist/bin/harper.js.map +1 -1
- package/dist/bin/help.js +4 -1
- package/dist/bin/help.js.map +1 -1
- package/dist/bin/lite.js +4 -1
- package/dist/bin/lite.js.map +1 -1
- package/dist/bin/restart.js +91 -6
- package/dist/bin/restart.js.map +1 -1
- package/dist/bin/run.js +4 -10
- package/dist/bin/run.js.map +1 -1
- package/dist/bin/upgrade.js +4 -3
- package/dist/bin/upgrade.js.map +1 -1
- package/dist/bin/workloadIdentity.d.ts +18 -0
- package/dist/bin/workloadIdentity.js +100 -0
- package/dist/bin/workloadIdentity.js.map +1 -0
- package/dist/components/Application.d.ts +235 -17
- package/dist/components/Application.js +3038 -238
- package/dist/components/Application.js.map +1 -1
- package/dist/components/ApplicationScope.d.ts +8 -0
- package/dist/components/ApplicationScope.js +7 -0
- package/dist/components/ApplicationScope.js.map +1 -1
- package/dist/components/EntryHandler.js +26 -10
- package/dist/components/EntryHandler.js.map +1 -1
- package/dist/components/OptionsWatcher.d.ts +4 -0
- package/dist/components/OptionsWatcher.js +440 -99
- package/dist/components/OptionsWatcher.js.map +1 -1
- package/dist/components/RuntimeModuleTracker.js +40 -6
- package/dist/components/RuntimeModuleTracker.js.map +1 -1
- package/dist/components/Scope.js +52 -13
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/awaitRestart.d.ts +33 -0
- package/dist/components/awaitRestart.js +61 -0
- package/dist/components/awaitRestart.js.map +1 -0
- package/dist/components/componentLoader.d.ts +38 -1
- package/dist/components/componentLoader.js +313 -24
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/componentPreparationLock.d.ts +5 -0
- package/dist/components/componentPreparationLock.js +14 -6
- package/dist/components/componentPreparationLock.js.map +1 -1
- package/dist/components/deploymentOperations.js +4 -1
- package/dist/components/deploymentOperations.js.map +1 -1
- package/dist/components/deploymentRecorder.d.ts +4 -2
- package/dist/components/deploymentRecorder.js +1 -0
- package/dist/components/deploymentRecorder.js.map +1 -1
- package/dist/components/mcp/adapters/harperHttp.js +4 -0
- package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
- package/dist/components/mcp/listChanged.js +5 -0
- package/dist/components/mcp/listChanged.js.map +1 -1
- package/dist/components/mcp/toolRegistry.d.ts +1 -0
- package/dist/components/mcp/toolRegistry.js.map +1 -1
- package/dist/components/mcp/tools/operations.d.ts +5 -0
- package/dist/components/mcp/tools/operations.js +9 -0
- package/dist/components/mcp/tools/operations.js.map +1 -1
- package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
- package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
- package/dist/components/operations.d.ts +28 -0
- package/dist/components/operations.js +476 -113
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.js +97 -3
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/components/packageComponent.js +24 -0
- package/dist/components/packageComponent.js.map +1 -1
- package/dist/components/requestRestart.d.ts +1 -0
- package/dist/components/requestRestart.js +7 -0
- package/dist/components/requestRestart.js.map +1 -1
- package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
- package/dist/components/status/ComponentStatusRegistry.js +63 -0
- package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
- package/dist/config/RootConfigWatcher.d.ts +9 -1
- package/dist/config/RootConfigWatcher.js +228 -37
- package/dist/config/RootConfigWatcher.js.map +1 -1
- package/dist/config/configReadRetry.d.ts +8 -0
- package/dist/config/configReadRetry.js +62 -0
- package/dist/config/configReadRetry.js.map +1 -0
- package/dist/config/configUtils.d.ts +11 -2
- package/dist/config/configUtils.js +304 -47
- package/dist/config/configUtils.js.map +1 -1
- package/dist/config/harperConfigEnvVars.d.ts +16 -0
- package/dist/config/harperConfigEnvVars.js +162 -25
- package/dist/config/harperConfigEnvVars.js.map +1 -1
- package/dist/config/parseConfigFile.d.ts +4 -0
- package/dist/config/parseConfigFile.js +35 -0
- package/dist/config/parseConfigFile.js.map +1 -0
- package/dist/config/readConfigFileSync.d.ts +1 -0
- package/dist/config/readConfigFileSync.js +47 -0
- package/dist/config/readConfigFileSync.js.map +1 -0
- package/dist/config/watcherArming.d.ts +15 -0
- package/dist/config/watcherArming.js +59 -0
- package/dist/config/watcherArming.js.map +1 -0
- package/dist/dataLayer/blobBackup.d.ts +49 -20
- package/dist/dataLayer/blobBackup.js +139 -50
- package/dist/dataLayer/blobBackup.js.map +1 -1
- package/dist/dataLayer/delete.js +1 -1
- package/dist/dataLayer/delete.js.map +1 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.js +72 -12
- package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
- package/dist/dataLayer/hdbInfoController.d.ts +10 -0
- package/dist/dataLayer/hdbInfoController.js +30 -1
- package/dist/dataLayer/hdbInfoController.js.map +1 -1
- package/dist/dataLayer/insert.d.ts +9 -1
- package/dist/dataLayer/insert.js +30 -0
- package/dist/dataLayer/insert.js.map +1 -1
- package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
- package/dist/dataLayer/rocksdbBackup.js +45 -8
- package/dist/dataLayer/rocksdbBackup.js.map +1 -1
- package/dist/dataLayer/schema.js +8 -0
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +8 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/json/systemSchema.json +55 -0
- package/dist/resources/DatabaseTransaction.d.ts +77 -0
- package/dist/resources/DatabaseTransaction.js +586 -54
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/LMDBTransaction.d.ts +2 -1
- package/dist/resources/LMDBTransaction.js +43 -6
- package/dist/resources/LMDBTransaction.js.map +1 -1
- package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
- package/dist/resources/PrimaryRocksDatabase.js +49 -5
- package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
- package/dist/resources/RecordEncoder.d.ts +20 -0
- package/dist/resources/RecordEncoder.js +110 -9
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/RequestTarget.d.ts +2 -0
- package/dist/resources/RequestTarget.js.map +1 -1
- package/dist/resources/Resource.js +117 -24
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +28 -1
- package/dist/resources/ResourceInterface.js.map +1 -1
- package/dist/resources/RocksIndexStore.d.ts +6 -1
- package/dist/resources/RocksIndexStore.js +24 -9
- package/dist/resources/RocksIndexStore.js.map +1 -1
- package/dist/resources/RocksTransactionLogStore.d.ts +24 -1
- package/dist/resources/RocksTransactionLogStore.js +160 -49
- package/dist/resources/RocksTransactionLogStore.js.map +1 -1
- package/dist/resources/Table.d.ts +165 -10
- package/dist/resources/Table.js +1805 -303
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/write.js +10 -3
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/auditStore.d.ts +181 -2
- package/dist/resources/auditStore.js +640 -29
- package/dist/resources/auditStore.js.map +1 -1
- package/dist/resources/blob.d.ts +129 -9
- package/dist/resources/blob.js +992 -114
- package/dist/resources/blob.js.map +1 -1
- package/dist/resources/branchDatabase.d.ts +48 -0
- package/dist/resources/branchDatabase.js +892 -0
- package/dist/resources/branchDatabase.js.map +1 -0
- package/dist/resources/crdt.js +50 -12
- package/dist/resources/crdt.js.map +1 -1
- package/dist/resources/dataLoader.js +3 -4
- package/dist/resources/dataLoader.js.map +1 -1
- package/dist/resources/databases.d.ts +157 -14
- package/dist/resources/databases.js +1462 -325
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/defineTable.d.ts +10 -2
- package/dist/resources/defineTable.js +9 -1
- package/dist/resources/defineTable.js.map +1 -1
- package/dist/resources/derivedIndexRegistry.d.ts +5 -0
- package/dist/resources/derivedIndexRegistry.js +68 -0
- package/dist/resources/derivedIndexRegistry.js.map +1 -0
- package/dist/resources/derivedIndexRuntime.d.ts +215 -0
- package/dist/resources/derivedIndexRuntime.js +2027 -0
- package/dist/resources/derivedIndexRuntime.js.map +1 -0
- package/dist/resources/graphql.d.ts +1 -1
- package/dist/resources/graphql.js +52 -16
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +103 -9
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +854 -41
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/resources/indexes/hnswDerivedIndex.d.ts +67 -0
- package/dist/resources/indexes/hnswDerivedIndex.js +464 -0
- package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -0
- package/dist/resources/indexes/hnswPlaneBinding.d.ts +65 -0
- package/dist/resources/indexes/hnswPlaneBinding.js +91 -0
- package/dist/resources/indexes/hnswPlaneBinding.js.map +1 -0
- package/dist/resources/longLivedTransactions.d.ts +71 -0
- package/dist/resources/longLivedTransactions.js +358 -0
- package/dist/resources/longLivedTransactions.js.map +1 -0
- package/dist/resources/models/backendRegistry.d.ts +26 -0
- package/dist/resources/models/backendRegistry.js +60 -2
- package/dist/resources/models/backendRegistry.js.map +1 -1
- package/dist/resources/models/bootstrap.d.ts +33 -1
- package/dist/resources/models/bootstrap.js +416 -31
- package/dist/resources/models/bootstrap.js.map +1 -1
- package/dist/resources/nodeIdMapping.d.ts +5 -0
- package/dist/resources/nodeIdMapping.js +49 -0
- package/dist/resources/nodeIdMapping.js.map +1 -1
- package/dist/resources/recordLock.d.ts +123 -0
- package/dist/resources/recordLock.js +315 -0
- package/dist/resources/recordLock.js.map +1 -0
- package/dist/resources/recordLockCoordinator.d.ts +557 -0
- package/dist/resources/recordLockCoordinator.js +2565 -0
- package/dist/resources/recordLockCoordinator.js.map +1 -0
- package/dist/resources/replayLogs.d.ts +14 -1
- package/dist/resources/replayLogs.js +157 -24
- package/dist/resources/replayLogs.js.map +1 -1
- package/dist/resources/replayLogsGuards.d.ts +94 -7
- package/dist/resources/replayLogsGuards.js +111 -7
- package/dist/resources/replayLogsGuards.js.map +1 -1
- package/dist/resources/replicatedApplyFailure.d.ts +16 -0
- package/dist/resources/replicatedApplyFailure.js +63 -0
- package/dist/resources/replicatedApplyFailure.js.map +1 -0
- package/dist/resources/scheduler/scheduler.js +3 -3
- package/dist/resources/scheduler/scheduler.js.map +1 -1
- package/dist/resources/search.d.ts +10 -4
- package/dist/resources/search.js +283 -37
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/tracked.d.ts +5 -1
- package/dist/resources/tracked.js +74 -23
- package/dist/resources/tracked.js.map +1 -1
- package/dist/resources/transactionBroadcast.d.ts +1 -1
- package/dist/resources/transactionBroadcast.js +2 -2
- package/dist/resources/transactionBroadcast.js.map +1 -1
- package/dist/security/auth.js +61 -30
- package/dist/security/auth.js.map +1 -1
- package/dist/security/authn/oidc/claims.d.ts +22 -0
- package/dist/security/authn/oidc/claims.js +71 -0
- package/dist/security/authn/oidc/claims.js.map +1 -0
- package/dist/security/authn/oidc/identityToken.d.ts +27 -0
- package/dist/security/authn/oidc/identityToken.js +111 -0
- package/dist/security/authn/oidc/identityToken.js.map +1 -0
- package/dist/security/authn/oidc/jwks.d.ts +25 -0
- package/dist/security/authn/oidc/jwks.js +261 -0
- package/dist/security/authn/oidc/jwks.js.map +1 -0
- package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
- package/dist/security/authn/oidc/providers/generic.js +34 -0
- package/dist/security/authn/oidc/providers/generic.js.map +1 -0
- package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
- package/dist/security/authn/oidc/providers/githubActions.js +129 -0
- package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
- package/dist/security/authn/oidc/providers/index.d.ts +37 -0
- package/dist/security/authn/oidc/providers/index.js +24 -0
- package/dist/security/authn/oidc/providers/index.js.map +1 -0
- package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
- package/dist/security/authn/oidc/tokenExchange.js +306 -0
- package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
- package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
- package/dist/security/authn/oidc/types.d.ts +38 -0
- package/dist/security/authn/oidc/types.js +6 -0
- package/dist/security/authn/oidc/types.js.map +1 -0
- package/dist/security/certificateVerification/index.js +40 -11
- package/dist/security/certificateVerification/index.js.map +1 -1
- package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
- package/dist/security/certificateVerification/trustedIssuers.js +79 -0
- package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
- package/dist/security/certificateVerification/types.d.ts +1 -0
- package/dist/security/credentialProvenance.d.ts +35 -0
- package/dist/security/credentialProvenance.js +51 -0
- package/dist/security/credentialProvenance.js.map +1 -0
- package/dist/security/credentialRejection.d.ts +4 -0
- package/dist/security/credentialRejection.js +24 -0
- package/dist/security/credentialRejection.js.map +1 -0
- package/dist/security/deferredAuthentication.d.ts +36 -0
- package/dist/security/deferredAuthentication.js +70 -0
- package/dist/security/deferredAuthentication.js.map +1 -0
- package/dist/security/impersonation.d.ts +21 -0
- package/dist/security/impersonation.js +108 -9
- package/dist/security/impersonation.js.map +1 -1
- package/dist/security/jsLoader.d.ts +6 -0
- package/dist/security/jsLoader.js +77 -15
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +301 -71
- package/dist/security/keys.js.map +1 -1
- package/dist/security/operationScope.d.ts +21 -0
- package/dist/security/operationScope.js +36 -0
- package/dist/security/operationScope.js.map +1 -0
- package/dist/security/permissionsTranslator.js +21 -0
- package/dist/security/permissionsTranslator.js.map +1 -1
- package/dist/security/tokenAuthentication.d.ts +19 -1
- package/dist/security/tokenAuthentication.js +191 -10
- package/dist/security/tokenAuthentication.js.map +1 -1
- package/dist/security/user.js +4 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
- package/dist/server/DurableSubscriptionsSession.js +67 -10
- package/dist/server/DurableSubscriptionsSession.js.map +1 -1
- package/dist/server/REST.js +106 -2
- package/dist/server/REST.js.map +1 -1
- package/dist/server/graphqlQuerying.js +4 -0
- package/dist/server/graphqlQuerying.js.map +1 -1
- package/dist/server/http.d.ts +16 -1
- package/dist/server/http.js +122 -17
- package/dist/server/http.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +8 -1
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/server/jobs/jobProcess.js +6 -2
- package/dist/server/jobs/jobProcess.js.map +1 -1
- package/dist/server/jobs/jobs.js +4 -1
- package/dist/server/jobs/jobs.js.map +1 -1
- package/dist/server/liveSubscriptionAuth.d.ts +26 -4
- package/dist/server/liveSubscriptionAuth.js +105 -39
- package/dist/server/liveSubscriptionAuth.js.map +1 -1
- package/dist/server/loadRootComponents.js +49 -10
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/mqtt.d.ts +2 -0
- package/dist/server/mqtt.js +165 -30
- package/dist/server/mqtt.js.map +1 -1
- package/dist/server/nodeName.d.ts +2 -0
- package/dist/server/nodeName.js +107 -23
- package/dist/server/nodeName.js.map +1 -1
- package/dist/server/serverHelpers/Headers.d.ts +27 -0
- package/dist/server/serverHelpers/Headers.js +145 -1
- package/dist/server/serverHelpers/Headers.js.map +1 -1
- package/dist/server/serverHelpers/NodeAdapterResponse.d.ts +48 -0
- package/dist/server/serverHelpers/NodeAdapterResponse.js +220 -0
- package/dist/server/serverHelpers/NodeAdapterResponse.js.map +1 -0
- package/dist/server/serverHelpers/Request.d.ts +5 -10
- package/dist/server/serverHelpers/Request.js +38 -136
- package/dist/server/serverHelpers/Request.js.map +1 -1
- package/dist/server/serverHelpers/contentTypes.d.ts +11 -0
- package/dist/server/serverHelpers/contentTypes.js +221 -40
- package/dist/server/serverHelpers/contentTypes.js.map +1 -1
- package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
- package/dist/server/serverHelpers/deployValidationState.js +9 -19
- package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
- package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
- package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
- package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
- package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
- package/dist/server/serverHelpers/registeredOperations.js +74 -21
- package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
- package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
- package/dist/server/serverHelpers/requestSanitization.js +20 -0
- package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
- package/dist/server/serverHelpers/serverHandlers.js +6 -3
- package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
- package/dist/server/serverHelpers/serverUtilities.js +178 -29
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
- package/dist/server/serverHelpers/uwsServer.js +19 -1
- package/dist/server/serverHelpers/uwsServer.js.map +1 -1
- package/dist/server/static.js +24 -28
- package/dist/server/static.js.map +1 -1
- package/dist/server/storageReclamation.d.ts +5 -0
- package/dist/server/storageReclamation.js +17 -1
- package/dist/server/storageReclamation.js.map +1 -1
- package/dist/server/threads/isolatedApplications.d.ts +47 -0
- package/dist/server/threads/isolatedApplications.js +171 -0
- package/dist/server/threads/isolatedApplications.js.map +1 -0
- package/dist/server/threads/itc.d.ts +7 -2
- package/dist/server/threads/itc.js +5 -1
- package/dist/server/threads/itc.js.map +1 -1
- package/dist/server/threads/logRotationTransport.d.ts +1 -0
- package/dist/server/threads/logRotationTransport.js +33 -0
- package/dist/server/threads/logRotationTransport.js.map +1 -0
- package/dist/server/threads/manageThreads.d.ts +83 -3
- package/dist/server/threads/manageThreads.js +769 -75
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.d.ts +1 -0
- package/dist/server/threads/socketRouter.js +277 -31
- package/dist/server/threads/socketRouter.js.map +1 -1
- package/dist/server/threads/threadHeapMemory.d.ts +2 -0
- package/dist/server/threads/threadHeapMemory.js +31 -0
- package/dist/server/threads/threadHeapMemory.js.map +1 -0
- package/dist/server/threads/threadServer.js +76 -22
- package/dist/server/threads/threadServer.js.map +1 -1
- package/dist/sqlEngine/config.d.ts +1 -3
- package/dist/sqlEngine/config.js +19 -16
- package/dist/sqlEngine/config.js.map +1 -1
- package/dist/sqlTranslator/index.d.ts +1 -1
- package/dist/sqlTranslator/index.js +30 -7
- package/dist/sqlTranslator/index.js.map +1 -1
- package/dist/upgrade/directives/5-3-0.d.ts +7 -0
- package/dist/upgrade/directives/5-3-0.js +148 -0
- package/dist/upgrade/directives/5-3-0.js.map +1 -0
- package/dist/upgrade/directives/directivesController.js +2 -1
- package/dist/upgrade/directives/directivesController.js.map +1 -1
- package/dist/utility/OperationFunctionCaller.js +2 -1
- package/dist/utility/OperationFunctionCaller.js.map +1 -1
- package/dist/utility/common_utils.d.ts +16 -0
- package/dist/utility/common_utils.js +32 -6
- package/dist/utility/common_utils.js.map +1 -1
- package/dist/utility/componentNames.d.ts +8 -0
- package/dist/utility/componentNames.js +12 -1
- package/dist/utility/componentNames.js.map +1 -1
- package/dist/utility/environment/environmentManager.js +3 -6
- package/dist/utility/environment/environmentManager.js.map +1 -1
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/environment/systemInformation.js +1 -0
- package/dist/utility/environment/systemInformation.js.map +1 -1
- package/dist/utility/errors/commonErrors.d.ts +2 -0
- package/dist/utility/errors/commonErrors.js +2 -0
- package/dist/utility/errors/commonErrors.js.map +1 -1
- package/dist/utility/errors/hdbError.d.ts +33 -0
- package/dist/utility/errors/hdbError.js +58 -1
- package/dist/utility/errors/hdbError.js.map +1 -1
- package/dist/utility/globalSchema.d.ts +18 -0
- package/dist/utility/hdbTerms.d.ts +18 -0
- package/dist/utility/hdbTerms.js +20 -2
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/logging/harper_logger.d.ts +2 -0
- package/dist/utility/logging/harper_logger.js +286 -30
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/dist/utility/logging/logGenerationCoordinator.d.ts +35 -0
- package/dist/utility/logging/logGenerationCoordinator.js +184 -0
- package/dist/utility/logging/logGenerationCoordinator.js.map +1 -0
- package/dist/utility/logging/logRotation.d.ts +46 -0
- package/dist/utility/logging/logRotation.js +365 -0
- package/dist/utility/logging/logRotation.js.map +1 -0
- package/dist/utility/logging/logRotator.d.ts +1 -1
- package/dist/utility/logging/logRotator.js +192 -85
- package/dist/utility/logging/logRotator.js.map +1 -1
- package/dist/utility/nodeIdentity.d.ts +9 -0
- package/dist/utility/nodeIdentity.js +58 -0
- package/dist/utility/nodeIdentity.js.map +1 -0
- package/dist/utility/npmUtilities.js +11 -7
- package/dist/utility/npmUtilities.js.map +1 -1
- package/dist/utility/operationPermissions.d.ts +3 -1
- package/dist/utility/operationPermissions.js +16 -1
- package/dist/utility/operationPermissions.js.map +1 -1
- package/dist/utility/operation_authorization.d.ts +10 -7
- package/dist/utility/operation_authorization.js +212 -41
- package/dist/utility/operation_authorization.js.map +1 -1
- package/dist/utility/watchPath.d.ts +29 -0
- package/dist/utility/watchPath.js +68 -0
- package/dist/utility/watchPath.js.map +1 -0
- package/dist/utility/watcherFallback.d.ts +41 -0
- package/dist/utility/watcherFallback.js +153 -0
- package/dist/utility/watcherFallback.js.map +1 -1
- package/dist/validation/configValidator.d.ts +12 -0
- package/dist/validation/configValidator.js +205 -75
- package/dist/validation/configValidator.js.map +1 -1
- package/dist/validation/installValidator.js +12 -0
- package/dist/validation/installValidator.js.map +1 -1
- package/dist/validation/validationWrapper.d.ts +11 -0
- package/dist/validation/validationWrapper.js +16 -3
- package/dist/validation/validationWrapper.js.map +1 -1
- package/index.ts +8 -0
- package/json/systemSchema.json +55 -0
- package/npm-shrinkwrap.json +286 -194
- package/package.json +15 -7
- package/resources/DESIGN.md +219 -52
- package/resources/DatabaseTransaction.ts +657 -52
- package/resources/LMDBTransaction.ts +46 -6
- package/resources/PrimaryRocksDatabase.ts +46 -7
- package/resources/RecordEncoder.ts +124 -9
- package/resources/RequestTarget.ts +2 -0
- package/resources/Resource.ts +114 -22
- package/resources/ResourceInterface.ts +31 -0
- package/resources/RocksIndexStore.ts +30 -9
- package/resources/RocksTransactionLogStore.ts +188 -51
- package/resources/Table.ts +1960 -301
- package/resources/analytics/write.ts +10 -3
- package/resources/auditStore.ts +647 -32
- package/resources/blob.ts +1029 -110
- package/resources/branchDatabase.ts +941 -0
- package/resources/crdt.ts +76 -12
- package/resources/dataLoader.ts +3 -4
- package/resources/databases.ts +1584 -320
- package/resources/defineTable.ts +18 -2
- package/resources/derivedIndexRegistry.ts +56 -0
- package/resources/derivedIndexRuntime.ts +2292 -0
- package/resources/graphql.ts +72 -17
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +911 -48
- package/resources/indexes/hnswDerivedIndex.ts +531 -0
- package/resources/indexes/hnswPlaneBinding.ts +174 -0
- package/resources/longLivedTransactions.ts +360 -0
- package/resources/models/backendRegistry.ts +84 -2
- package/resources/models/bootstrap.ts +473 -28
- package/resources/nodeIdMapping.ts +50 -0
- package/resources/recordLock.ts +419 -0
- package/resources/recordLockCoordinator.ts +3043 -0
- package/resources/replayLogs.ts +152 -26
- package/resources/replayLogsGuards.ts +171 -8
- package/resources/replicatedApplyFailure.ts +77 -0
- package/resources/scheduler/scheduler.ts +4 -4
- package/resources/search.ts +288 -46
- package/resources/tracked.ts +73 -22
- package/resources/transactionBroadcast.ts +3 -3
- package/security/auth.ts +68 -29
- package/security/authn/oidc/claims.ts +72 -0
- package/security/authn/oidc/identityToken.ts +129 -0
- package/security/authn/oidc/jwks.ts +260 -0
- package/security/authn/oidc/providers/generic.ts +40 -0
- package/security/authn/oidc/providers/githubActions.ts +137 -0
- package/security/authn/oidc/providers/index.ts +52 -0
- package/security/authn/oidc/tokenExchange.ts +300 -0
- package/security/authn/oidc/trustPolicyOperations.ts +343 -0
- package/security/authn/oidc/types.ts +41 -0
- package/security/certificateVerification/index.ts +54 -13
- package/security/certificateVerification/trustedIssuers.ts +76 -0
- package/security/certificateVerification/types.ts +1 -0
- package/security/credentialProvenance.ts +47 -0
- package/security/credentialRejection.ts +22 -0
- package/security/deferredAuthentication.ts +71 -0
- package/security/impersonation.ts +117 -12
- package/security/jsLoader.ts +83 -18
- package/security/keys.ts +298 -72
- package/security/operationScope.ts +33 -0
- package/security/permissionsTranslator.js +23 -0
- package/security/tokenAuthentication.ts +233 -12
- package/security/user.ts +4 -3
- package/server/DESIGN.md +194 -16
- package/server/DurableSubscriptionsSession.ts +71 -11
- package/server/REST.ts +115 -4
- package/server/graphqlQuerying.ts +4 -0
- package/server/http.ts +133 -20
- package/server/itc/serverHandlers.js +8 -1
- package/server/jobs/jobProcess.ts +8 -2
- package/server/jobs/jobs.ts +4 -1
- package/server/liveSubscriptionAuth.ts +129 -46
- package/server/loadRootComponents.js +50 -8
- package/server/mqtt.ts +179 -38
- package/server/nodeName.ts +103 -21
- package/server/serverHelpers/Headers.ts +135 -0
- package/server/serverHelpers/NodeAdapterResponse.ts +221 -0
- package/server/serverHelpers/Request.ts +33 -131
- package/server/serverHelpers/contentTypes.ts +217 -36
- package/server/serverHelpers/deployValidationState.ts +24 -13
- package/server/serverHelpers/operationAuthorizationState.ts +34 -3
- package/server/serverHelpers/registeredOperations.ts +79 -22
- package/server/serverHelpers/requestSanitization.ts +15 -0
- package/server/serverHelpers/serverHandlers.js +6 -3
- package/server/serverHelpers/serverUtilities.ts +232 -40
- package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
- package/server/serverHelpers/uwsServer.ts +17 -2
- package/server/static.ts +23 -29
- package/server/storageReclamation.ts +15 -2
- package/server/threads/isolatedApplications.ts +157 -0
- package/server/threads/itc.js +11 -1
- package/server/threads/logRotationTransport.ts +40 -0
- package/server/threads/manageThreads.js +771 -66
- package/server/threads/socketRouter.ts +291 -30
- package/server/threads/threadHeapMemory.ts +26 -0
- package/server/threads/threadServer.js +73 -22
- package/sqlTranslator/index.ts +31 -8
- package/studio/web/assets/{Chat-4RrB5134.js → Chat-D3j-1yY1.js} +1 -1
- package/studio/web/assets/{FloatingChat-omlNMDcJ.js → FloatingChat-BxJGYcfB.js} +3 -3
- package/studio/web/assets/{apiToken-Bke3wvfZ.js → apiToken-CT55oWOe.js} +1 -1
- package/studio/web/assets/{applications-DvFDYJgK.js → applications-D9Ct9_vm.js} +1 -1
- package/studio/web/assets/{cssMode-C1vRa7zh.js → cssMode-DV8H7VwA.js} +1 -1
- package/studio/web/assets/{editor-3XRWEDWX.js → editor-uatc0unt.js} +1 -1
- package/studio/web/assets/{html-CTY5tdMr.js → html-Bm6D6paN.js} +1 -1
- package/studio/web/assets/{htmlMode-CG1vSD9t.js → htmlMode-CEn7tpLG.js} +1 -1
- package/studio/web/assets/{index-Dfpeofdu.js → index-BIXW6Pu4.js} +5 -5
- package/studio/web/assets/{index.lazy-B1VOIv-t.js → index.lazy-UI7L-Vrk.js} +1 -1
- package/studio/web/assets/{javascript-CJeJzGnI.js → javascript-CJ0G3AFZ.js} +1 -1
- package/studio/web/assets/{jsonMode-CYPBwM82.js → jsonMode-DQADAYEa.js} +1 -1
- package/studio/web/assets/{languageServices-IKH4GUHl.js → languageServices-CAQJXWcI.js} +1 -1
- package/studio/web/assets/{lspLanguageFeatures-BC8_gxKG.js → lspLanguageFeatures-CCQ8P5sY.js} +1 -1
- package/studio/web/assets/{notifications-BfKBpYcq.js → notifications-BbxTU6Aw.js} +1 -1
- package/studio/web/assets/{notifications-DFbArTfC.js → notifications-Cvb3P1lB.js} +1 -1
- package/studio/web/assets/{profile-Q4-T6c-S.js → profile-Yyb7gsvL.js} +1 -1
- package/studio/web/assets/{regions-CtkV0xje.js → regions-OgjGHlU5.js} +1 -1
- package/studio/web/assets/{register-1ZZuMsiA.js → register-6qwNEOY3.js} +2 -2
- package/studio/web/assets/{setComponentFile-ZWLcWv5X.js → setComponentFile-BilDMtgB.js} +1 -1
- package/studio/web/assets/{setup-DWprJyJy.js → setup-J6qJ7OIU.js} +2 -2
- package/studio/web/assets/{status--aNm8isn.js → status-0RWGcfyD.js} +1 -1
- package/studio/web/assets/{toggleHighContrast-Cq_lt3XD.js → toggleHighContrast-BIn-vErT.js} +1 -1
- package/studio/web/assets/{tsMode-pjgytARx.js → tsMode-DgUXku4d.js} +1 -1
- package/studio/web/assets/{typescript-Cdg0mqUh.js → typescript-C9orXcsM.js} +1 -1
- package/studio/web/assets/{useEntityRestURL-RZhaY8Rn.js → useEntityRestURL-BEoXXbUB.js} +1 -1
- package/studio/web/assets/{workers-BgoXIqQe.js → workers-JVzSDmgx.js} +1 -1
- package/studio/web/assets/{xml-BwSeDMiP.js → xml-Cq-S8S4X.js} +1 -1
- package/studio/web/assets/{yaml-DotCUG5l.js → yaml-sfoRdh1M.js} +1 -1
- package/studio/web/index.html +1 -1
- package/upgrade/directives/5-3-0.ts +132 -0
- package/upgrade/directives/directivesController.ts +2 -1
- package/utility/OperationFunctionCaller.ts +2 -1
- package/utility/common_utils.ts +30 -5
- package/utility/componentNames.ts +12 -0
- package/utility/environment/environmentManager.ts +3 -7
- package/utility/environment/systemInformation.ts +7 -0
- package/utility/errors/commonErrors.ts +4 -0
- package/utility/errors/hdbError.ts +57 -0
- package/utility/hdbTerms.ts +19 -0
- package/utility/logging/harper_logger.ts +278 -26
- package/utility/logging/logGenerationCoordinator.ts +196 -0
- package/utility/logging/logRotation.ts +367 -0
- package/utility/logging/logRotator.ts +213 -81
- package/utility/nodeIdentity.ts +45 -0
- package/utility/npmUtilities.ts +12 -8
- package/utility/operationPermissions.ts +18 -1
- package/utility/operation_authorization.ts +231 -42
- package/utility/watchPath.ts +63 -0
- package/utility/watcherFallback.ts +148 -0
- package/validation/configValidator.ts +215 -75
- package/validation/installValidator.ts +15 -0
- package/validation/validationWrapper.ts +18 -4
|
@@ -38,7 +38,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.resolvePath = resolvePath;
|
|
40
40
|
exports.getConfigPath = getConfigPath;
|
|
41
|
+
exports.isStorageExhausted = isStorageExhausted;
|
|
42
|
+
exports.persistConfigDuringBoot = persistConfigDuringBoot;
|
|
41
43
|
exports.atomicWriteFile = atomicWriteFile;
|
|
44
|
+
exports.renameWithRetry = renameWithRetry;
|
|
42
45
|
exports.createConfigFile = createConfigFile;
|
|
43
46
|
exports.getDefaultConfig = getDefaultConfig;
|
|
44
47
|
exports.getConfigValue = getConfigValue;
|
|
@@ -62,9 +65,11 @@ const hdbTerms = __importStar(require("../utility/hdbTerms.js"));
|
|
|
62
65
|
const hdbUtils = __importStar(require("../utility/common_utils.js"));
|
|
63
66
|
const harper_logger_ts_1 = __importDefault(require("../utility/logging/harper_logger.js"));
|
|
64
67
|
const configValidator_ts_1 = require("../validation/configValidator.js");
|
|
68
|
+
const componentNames_ts_1 = require("../utility/componentNames.js");
|
|
65
69
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
66
70
|
const yaml_1 = __importDefault(require("yaml"));
|
|
67
71
|
const path_1 = __importDefault(require("path"));
|
|
72
|
+
const node_os_1 = require("node:os");
|
|
68
73
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
69
74
|
const node_crypto_1 = require("node:crypto");
|
|
70
75
|
const is_number_1 = __importDefault(require("is-number"));
|
|
@@ -84,6 +89,7 @@ const packageUtils_js_1 = require("../utility/packageUtils.js");
|
|
|
84
89
|
const env = __importStar(require("../utility/environment/environmentManager.js"));
|
|
85
90
|
const harperConfigEnvVars_ts_1 = require("./harperConfigEnvVars.js");
|
|
86
91
|
const componentEnvPrepass_ts_1 = require("./componentEnvPrepass.js");
|
|
92
|
+
const threadHeapMemory_ts_1 = require("../server/threads/threadHeapMemory.js");
|
|
87
93
|
const { DATABASES_PARAM_CONFIG, CONFIG_PARAMS, CONFIG_PARAM_MAP } = hdbTerms;
|
|
88
94
|
const UNINIT_GET_CONFIG_ERR = 'Unable to get config value because config is uninitialized';
|
|
89
95
|
const CONFIG_INIT_MSG = 'Config successfully initialized';
|
|
@@ -140,56 +146,154 @@ function getConfigPath(param) {
|
|
|
140
146
|
return value;
|
|
141
147
|
return path_1.default.resolve(rootPath, value);
|
|
142
148
|
}
|
|
143
|
-
// Write atomically via temp file + rename so readers
|
|
144
|
-
//
|
|
145
|
-
// in the same millisecond can't collide on the temp name and then race the rename.
|
|
146
|
-
//
|
|
149
|
+
// Write atomically via a randomized temp file + rename so readers do not observe partial content
|
|
150
|
+
// and concurrent workers, which share process.pid, do not collide on a temp path.
|
|
147
151
|
// Windows has no POSIX-style "replace an open file" semantics: rename() fails with
|
|
148
|
-
// EPERM/EACCES
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
//
|
|
156
|
-
const RENAME_RETRY_MAX_ATTEMPTS =
|
|
152
|
+
// EPERM/EACCES/EBUSY while another worker or AV holds the destination open. Root config watchers use
|
|
153
|
+
// readConfigFileSync so this blocking retry cannot wait on a read owned by its own worker.
|
|
154
|
+
// The budget is the wall-clock window of the 12-attempt schedule it replaced
|
|
155
|
+
// (10+20+40+80+160+320+500*6), so it stays a deadline rather than an attempt count without
|
|
156
|
+
// widening the stall: this loop blocks the calling worker's event loop, and `set_configuration`
|
|
157
|
+
// reaches it from a live request thread.
|
|
158
|
+
const RENAME_RETRY_BUDGET_MS = 3_630;
|
|
159
|
+
// Secondary guard only: stops a degenerate zero-delay option set from spinning the whole budget.
|
|
160
|
+
const RENAME_RETRY_MAX_ATTEMPTS = 25;
|
|
157
161
|
const RENAME_RETRY_INITIAL_DELAY_MS = 10;
|
|
158
162
|
const RENAME_RETRY_MAX_DELAY_MS = 500;
|
|
159
|
-
// Never notified;
|
|
163
|
+
// Never notified; Atomics.wait uses this only as a CPU-idle synchronous sleep.
|
|
160
164
|
const renameRetrySleepBuffer = new Int32Array(new SharedArrayBuffer(4));
|
|
161
|
-
|
|
165
|
+
// Classified by code alone rather than gated to win32 like the read side: `process.platform` does
|
|
166
|
+
// not answer whether this filesystem can replace an open file — WSL drvfs, CIFS/SMB and Docker
|
|
167
|
+
// Desktop bind mounts all report `linux` and return these codes transiently.
|
|
168
|
+
function isRetryableRenameError(code) {
|
|
169
|
+
return code === 'EPERM' || code === 'EACCES' || code === 'EBUSY';
|
|
170
|
+
}
|
|
171
|
+
function validateRenameRetryOptions({ retryBudgetMs, maxRetries, initialDelayMs, maxDelayMs }) {
|
|
172
|
+
const invalidOption = !Number.isFinite(retryBudgetMs) ||
|
|
173
|
+
retryBudgetMs < 0 ||
|
|
174
|
+
(!Number.isFinite(maxRetries) && maxRetries !== Infinity) ||
|
|
175
|
+
maxRetries < 0 ||
|
|
176
|
+
!Number.isFinite(initialDelayMs) ||
|
|
177
|
+
initialDelayMs < 0 ||
|
|
178
|
+
!Number.isFinite(maxDelayMs) ||
|
|
179
|
+
maxDelayMs < 0;
|
|
180
|
+
if (invalidOption) {
|
|
181
|
+
throw new RangeError('rename retry options must be non-negative numbers');
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Linux has no libuv mapping for EDQUOT, so a quota-exhausted write surfaces as
|
|
185
|
+
// `Unknown system error -122` with an unusable `code`; the numeric errno is the portable signal
|
|
186
|
+
// (EDQUOT is 122 on Linux, 69 on macOS).
|
|
187
|
+
const STORAGE_EXHAUSTED_CODES = new Set(['ENOSPC', 'EDQUOT']);
|
|
188
|
+
// EDQUOT is absent from os.constants.errno on platforms without quotas, so filter before negating:
|
|
189
|
+
// -undefined is NaN, which would sit in the set matching nothing and reading as a bug.
|
|
190
|
+
const STORAGE_EXHAUSTED_ERRNOS = new Set([node_os_1.constants.errno.ENOSPC, node_os_1.constants.errno.EDQUOT].filter((errno) => errno !== undefined).map((errno) => -errno));
|
|
191
|
+
function isStorageExhausted(error) {
|
|
192
|
+
return STORAGE_EXHAUSTED_CODES.has(error?.code) || STORAGE_EXHAUSTED_ERRNOS.has(error?.errno);
|
|
193
|
+
}
|
|
194
|
+
// Boot-path persistence of derived config is best-effort: on an exhausted volume a fatal write here
|
|
195
|
+
// is an un-breakable restart loop, because freeing space needs a started process (#847).
|
|
196
|
+
function persistConfigDuringBoot(artifactPath, write) {
|
|
197
|
+
try {
|
|
198
|
+
write();
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
if (!isStorageExhausted(error))
|
|
203
|
+
throw error;
|
|
204
|
+
harper_logger_ts_1.default.error(`Storage exhausted (${error.code ?? error.errno}) writing ${artifactPath}; continuing startup with the in-memory configuration. The file on disk is unchanged - free space on the Harper volume to restore config persistence.`);
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Returns true when the file was written, false when an unchanged write was skipped.
|
|
209
|
+
function atomicWriteFile(filePath, content, { retryBudgetMs = RENAME_RETRY_BUDGET_MS, maxRetries = RENAME_RETRY_MAX_ATTEMPTS, initialDelayMs = RENAME_RETRY_INITIAL_DELAY_MS, maxDelayMs = RENAME_RETRY_MAX_DELAY_MS, skipIfUnchanged = false, } = {}) {
|
|
210
|
+
// Before the temp write, so an option set that can never rename leaves no file behind.
|
|
211
|
+
validateRenameRetryOptions({ retryBudgetMs, maxRetries, initialDelayMs, maxDelayMs });
|
|
212
|
+
// Opt-in: skipping means no mtime bump, so no watcher event. Only callers that re-derive the
|
|
213
|
+
// same file every boot want that.
|
|
214
|
+
if (skipIfUnchanged && matchesFileContent(filePath, content))
|
|
215
|
+
return false;
|
|
162
216
|
const tempPath = `${filePath}.${process.pid}.${node_worker_threads_1.threadId}.${(0, node_crypto_1.randomBytes)(4).toString('hex')}.tmp`;
|
|
163
|
-
|
|
217
|
+
try {
|
|
218
|
+
fs_extra_1.default.writeFileSync(tempPath, content);
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
// The open succeeds before the write runs out of room, leaving the temp file behind.
|
|
222
|
+
removeTempFile(tempPath);
|
|
223
|
+
throw err;
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
renameWithRetry(tempPath, filePath, { retryBudgetMs, maxRetries, initialDelayMs, maxDelayMs });
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
// The temp name carries fresh randomness on every call, so a spent budget would otherwise
|
|
230
|
+
// leave a file nothing else will ever collect.
|
|
231
|
+
removeTempFile(tempPath);
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
function renameWithRetry(fromPath, toPath, { retryBudgetMs = RENAME_RETRY_BUDGET_MS, maxRetries = RENAME_RETRY_MAX_ATTEMPTS, initialDelayMs = RENAME_RETRY_INITIAL_DELAY_MS, maxDelayMs = RENAME_RETRY_MAX_DELAY_MS, } = {}) {
|
|
237
|
+
validateRenameRetryOptions({ retryBudgetMs, maxRetries, initialDelayMs, maxDelayMs });
|
|
164
238
|
let retries = maxRetries;
|
|
165
239
|
let delayMs = initialDelayMs;
|
|
240
|
+
let retryDeadline;
|
|
241
|
+
let finalAttempt = false;
|
|
242
|
+
let attempts = 0;
|
|
243
|
+
const startedAt = performance.now();
|
|
166
244
|
while (true) {
|
|
167
245
|
try {
|
|
168
|
-
|
|
169
|
-
|
|
246
|
+
attempts++;
|
|
247
|
+
fs_extra_1.default.renameSync(fromPath, toPath);
|
|
248
|
+
return;
|
|
170
249
|
}
|
|
171
250
|
catch (err) {
|
|
172
|
-
if (retries > 0 && (err.code
|
|
251
|
+
if (!finalAttempt && retries > 0 && isRetryableRenameError(err.code)) {
|
|
173
252
|
retries--;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
253
|
+
if (retryDeadline === undefined) {
|
|
254
|
+
retryDeadline = performance.now() + retryBudgetMs;
|
|
255
|
+
}
|
|
256
|
+
const remainingBudgetMs = retryDeadline - performance.now();
|
|
257
|
+
if (remainingBudgetMs > 0) {
|
|
258
|
+
// Sleep synchronously (all call sites are sync) to allow the holder to close the
|
|
259
|
+
// file. Atomics.wait yields the thread to the OS instead of spinning the CPU,
|
|
260
|
+
// which is what makes a multi-second worst-case budget affordable.
|
|
261
|
+
const sleepMs = Math.min(delayMs, remainingBudgetMs);
|
|
262
|
+
finalAttempt = sleepMs === remainingBudgetMs;
|
|
263
|
+
if (sleepMs > 0)
|
|
264
|
+
Atomics.wait(renameRetrySleepBuffer, 0, 0, sleepMs);
|
|
265
|
+
delayMs = Math.min(Math.max(delayMs * 2, RENAME_RETRY_INITIAL_DELAY_MS), maxDelayMs);
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
185
268
|
}
|
|
186
|
-
|
|
187
|
-
|
|
269
|
+
// Whether the budget was spent or the code was never retryable is the difference
|
|
270
|
+
// between a holder that never released and a one-off failure, and neither survives on
|
|
271
|
+
// the rethrown error.
|
|
272
|
+
if (isRetryableRenameError(err.code)) {
|
|
273
|
+
harper_logger_ts_1.default.warn(`Could not replace ${toPath}: ${err.code} after ${attempts} attempts over ${Math.round(performance.now() - startedAt)}ms`);
|
|
188
274
|
}
|
|
189
275
|
throw err;
|
|
190
276
|
}
|
|
191
277
|
}
|
|
192
278
|
}
|
|
279
|
+
function removeTempFile(tempPath) {
|
|
280
|
+
try {
|
|
281
|
+
fs_extra_1.default.unlinkSync(tempPath);
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// ignore cleanup errors
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function matchesFileContent(filePath, content) {
|
|
288
|
+
if (typeof content !== 'string')
|
|
289
|
+
return false;
|
|
290
|
+
try {
|
|
291
|
+
return fs_extra_1.default.readFileSync(filePath, 'utf8') === content;
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
193
297
|
/**
|
|
194
298
|
* Builds the Harper config file using user inputs and default values from defaultConfig.yaml
|
|
195
299
|
* @param args - any args that the user provided.
|
|
@@ -200,7 +304,7 @@ function createConfigFile(args, skipFsValidation = false) {
|
|
|
200
304
|
// Loop through the user inputted args. Match them to a parameter in the default config file and update value.
|
|
201
305
|
let schemasArgs;
|
|
202
306
|
for (const arg in args) {
|
|
203
|
-
let configParam =
|
|
307
|
+
let configParam = lookupConfigParam(arg);
|
|
204
308
|
// Schemas config args are handled differently, so if they exist set them to var that will be used by setSchemasConfig
|
|
205
309
|
if (configParam === CONFIG_PARAMS.DATABASES) {
|
|
206
310
|
if (Array.isArray(args[arg])) {
|
|
@@ -213,7 +317,7 @@ function createConfigFile(args, skipFsValidation = false) {
|
|
|
213
317
|
}
|
|
214
318
|
continue;
|
|
215
319
|
}
|
|
216
|
-
if (!configParam && (arg
|
|
320
|
+
if (!configParam && isSuffixEscapedParam(arg)) {
|
|
217
321
|
configParam = arg;
|
|
218
322
|
}
|
|
219
323
|
if (configParam !== undefined) {
|
|
@@ -306,7 +410,7 @@ function getDefaultConfig(param) {
|
|
|
306
410
|
const configDoc = parseYamlDoc(DEFAULT_CONFIG_FILE_PATH);
|
|
307
411
|
flatDefaultConfigObj = flattenConfig(configDoc.toJSON());
|
|
308
412
|
}
|
|
309
|
-
const paramMap =
|
|
413
|
+
const paramMap = lookupConfigParam(param);
|
|
310
414
|
if (paramMap === undefined)
|
|
311
415
|
return undefined;
|
|
312
416
|
return flatDefaultConfigObj[paramMap.toLowerCase()];
|
|
@@ -327,7 +431,7 @@ function getConfigValue(param) {
|
|
|
327
431
|
harper_logger_ts_1.default.trace(UNINIT_GET_CONFIG_ERR);
|
|
328
432
|
return undefined;
|
|
329
433
|
}
|
|
330
|
-
const paramMap =
|
|
434
|
+
const paramMap = lookupConfigParam(param);
|
|
331
435
|
if (paramMap === undefined)
|
|
332
436
|
return undefined;
|
|
333
437
|
return flatConfigObj[paramMap.toLowerCase()];
|
|
@@ -377,7 +481,11 @@ function ensureConfigKeysPresent(keys) {
|
|
|
377
481
|
}
|
|
378
482
|
if (added.length === 0)
|
|
379
483
|
return [];
|
|
380
|
-
|
|
484
|
+
// Worker threads re-read the config from disk and never run this backfill, so a key that only
|
|
485
|
+
// exists in this thread's memory activates nowhere that serves requests: report nothing when the
|
|
486
|
+
// write was refused rather than logging an activation the request path did not get.
|
|
487
|
+
if (!persistConfigDuringBoot(configFilePath, () => atomicWriteFile(configFilePath, String(configDoc))))
|
|
488
|
+
return [];
|
|
381
489
|
// Mirror the additions into the already-memoized config so a built-in gated on the new key
|
|
382
490
|
// activates on the CURRENT boot: componentLoader reads the root config from getConfigObj(),
|
|
383
491
|
// which is cached early in boot — before an upgrade backfill runs — so a file-only write would
|
|
@@ -566,7 +674,7 @@ function checkForUpdatedConfig(configDoc, configFilePath) {
|
|
|
566
674
|
if (configDoc.errors?.length > 0) {
|
|
567
675
|
throw (0, hdbError_ts_1.handleHDBError)(new Error(), `Error parsing harperdb-config.yaml ${configDoc.errors}`, commonErrors_ts_1.HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR);
|
|
568
676
|
}
|
|
569
|
-
atomicWriteFile(configFilePath, String(configDoc));
|
|
677
|
+
persistConfigDuringBoot(configFilePath, () => atomicWriteFile(configFilePath, String(configDoc)));
|
|
570
678
|
}
|
|
571
679
|
}
|
|
572
680
|
/**
|
|
@@ -636,6 +744,8 @@ function validateConfig(configDoc, skipFsValidation = false) {
|
|
|
636
744
|
const domainSocketWarning = (0, configValidator_ts_1.getDomainSocketPathLengthWarning)(validation.value.rootPath, domainSocket);
|
|
637
745
|
if (domainSocketWarning)
|
|
638
746
|
harper_logger_ts_1.default.warn(domainSocketWarning);
|
|
747
|
+
if ((0, configValidator_ts_1.isLegacySqlApplicationEntry)(configJson.sql))
|
|
748
|
+
harper_logger_ts_1.default.warn("The root config entry 'sql' is an application, but 'sql' now configures Harper's SQL engine. Redeploy that application under a different name and remove the 'sql' entry; until then the SQL engine settings cannot be configured.");
|
|
639
749
|
}
|
|
640
750
|
/**
|
|
641
751
|
* Updates the in memory flattened config object. Does not update the config file.
|
|
@@ -648,7 +758,7 @@ function updateConfigObject(param, value) {
|
|
|
648
758
|
// This is here to allow unit tests to work when HDB is not installed.
|
|
649
759
|
flatConfigObj = {};
|
|
650
760
|
}
|
|
651
|
-
const configObjKey =
|
|
761
|
+
const configObjKey = lookupConfigParam(param);
|
|
652
762
|
if (configObjKey === undefined) {
|
|
653
763
|
harper_logger_ts_1.default.trace(`Unable to update config object because config param '${param}' does not exist`);
|
|
654
764
|
return;
|
|
@@ -691,6 +801,69 @@ function updateConfigObject(param, value) {
|
|
|
691
801
|
node[leaf] = value;
|
|
692
802
|
}
|
|
693
803
|
}
|
|
804
|
+
/**
|
|
805
|
+
* Canonical config param for an arg name, or `undefined` when the name is not a config param.
|
|
806
|
+
* `Object.hasOwn` because a bare lookup resolves inherited names: `constructor` yields an
|
|
807
|
+
* `Object.prototype` member that then fails `.split('_')` or `.toLowerCase()`.
|
|
808
|
+
*/
|
|
809
|
+
function lookupConfigParam(arg) {
|
|
810
|
+
if (typeof arg !== 'string')
|
|
811
|
+
return undefined;
|
|
812
|
+
const name = arg.toLowerCase();
|
|
813
|
+
return Object.hasOwn(CONFIG_PARAM_MAP, name) ? CONFIG_PARAM_MAP[name] : undefined;
|
|
814
|
+
}
|
|
815
|
+
const COMPONENT_PARAM_SUFFIXES = ['_package', '_port'];
|
|
816
|
+
function suffixEscapedComponentName(arg) {
|
|
817
|
+
if (typeof arg !== 'string')
|
|
818
|
+
return undefined;
|
|
819
|
+
const suffix = COMPONENT_PARAM_SUFFIXES.find((candidate) => arg.endsWith(candidate));
|
|
820
|
+
if (suffix === undefined)
|
|
821
|
+
return undefined;
|
|
822
|
+
const component = arg.slice(0, -suffix.length);
|
|
823
|
+
return component === '' ? undefined : component;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Component entries (`my-component_package`, `my-component_port`) are operator-named, so they
|
|
827
|
+
* cannot be enumerated in CONFIG_PARAM_MAP and bypass it. This escape is the one way to write a
|
|
828
|
+
* root component entry without going through deploy_component, so a reserved name is excluded.
|
|
829
|
+
*/
|
|
830
|
+
function isSuffixEscapedParam(arg) {
|
|
831
|
+
const component = suffixEscapedComponentName(arg);
|
|
832
|
+
return component !== undefined && !(0, componentNames_ts_1.isReservedComponentName)(component);
|
|
833
|
+
}
|
|
834
|
+
function findReservedComponentParams(args) {
|
|
835
|
+
const reserved = [];
|
|
836
|
+
for (const arg in args) {
|
|
837
|
+
if (!Object.hasOwn(args, arg))
|
|
838
|
+
continue;
|
|
839
|
+
const component = suffixEscapedComponentName(arg);
|
|
840
|
+
if (component !== undefined && (0, componentNames_ts_1.isReservedComponentName)(component))
|
|
841
|
+
reserved.push(arg);
|
|
842
|
+
}
|
|
843
|
+
return reserved;
|
|
844
|
+
}
|
|
845
|
+
const MAX_REPORTED_UNRECOGNIZED = 10;
|
|
846
|
+
/**
|
|
847
|
+
* Render unrecognized names for an error that also reaches the operations log: control characters
|
|
848
|
+
* are stripped so a name containing a newline cannot forge a log line, and the list is capped so a
|
|
849
|
+
* body carrying thousands of unknown keys cannot produce an unbounded message.
|
|
850
|
+
*/
|
|
851
|
+
function describeUnrecognized(names) {
|
|
852
|
+
const shown = names
|
|
853
|
+
.slice(0, MAX_REPORTED_UNRECOGNIZED)
|
|
854
|
+
// eslint-disable-next-line no-control-regex
|
|
855
|
+
.map((name) => name.replace(/[\u0000-\u001f\u007f]/g, '?'));
|
|
856
|
+
const remaining = names.length - shown.length;
|
|
857
|
+
return remaining > 0 ? `${shown.join(', ')} (and ${remaining} more)` : shown.join(', ');
|
|
858
|
+
}
|
|
859
|
+
function findUnrecognizedParams(args) {
|
|
860
|
+
let unrecognized;
|
|
861
|
+
for (const arg in args) {
|
|
862
|
+
if (lookupConfigParam(arg) === undefined && !isSuffixEscapedParam(arg))
|
|
863
|
+
(unrecognized ??= []).push(arg);
|
|
864
|
+
}
|
|
865
|
+
return unrecognized ?? [];
|
|
866
|
+
}
|
|
694
867
|
/**
|
|
695
868
|
* Updates and validates a config value in config file. Can also create a backup of config before updating.
|
|
696
869
|
* @param param - the config value to update
|
|
@@ -741,7 +914,7 @@ function updateConfigValue(param, value, parsedArgs = undefined, createBackup =
|
|
|
741
914
|
configParam = param;
|
|
742
915
|
}
|
|
743
916
|
else {
|
|
744
|
-
configParam =
|
|
917
|
+
configParam = lookupConfigParam(param);
|
|
745
918
|
if (configParam === undefined) {
|
|
746
919
|
throw (0, hdbError_ts_1.handleHDBError)(new Error(), `Unable to update config, unrecognized config parameter: ${param}`, commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
|
|
747
920
|
}
|
|
@@ -753,7 +926,7 @@ function updateConfigValue(param, value, parsedArgs = undefined, createBackup =
|
|
|
753
926
|
else {
|
|
754
927
|
// Loop through the user inputted args. Match them to a parameter in the default config file and update value.
|
|
755
928
|
for (const arg in parsedArgs) {
|
|
756
|
-
let configParam =
|
|
929
|
+
let configParam = lookupConfigParam(arg);
|
|
757
930
|
// If setting http.securePort to the same value as http.port, set http.port to null to avoid clashing ports
|
|
758
931
|
if (configParam === CONFIG_PARAMS.HTTP_SECUREPORT &&
|
|
759
932
|
parsedArgs[arg] === flatConfigObj[CONFIG_PARAMS.HTTP_PORT]?.toString()) {
|
|
@@ -777,7 +950,7 @@ function updateConfigValue(param, value, parsedArgs = undefined, createBackup =
|
|
|
777
950
|
configDoc.setIn(['threads', 'count'], threadCount);
|
|
778
951
|
}
|
|
779
952
|
}
|
|
780
|
-
if (!configParam && (arg
|
|
953
|
+
if (!configParam && isSuffixEscapedParam(arg)) {
|
|
781
954
|
configParam = arg;
|
|
782
955
|
}
|
|
783
956
|
if (configParam !== undefined) {
|
|
@@ -947,14 +1120,49 @@ function getConfiguration() {
|
|
|
947
1120
|
const configDoc = parseYamlDoc(configFilePath);
|
|
948
1121
|
return configDoc.toJSON();
|
|
949
1122
|
}
|
|
1123
|
+
// `set_configuration` is the one config writer that also fans out (`replicated: true`), so a value
|
|
1124
|
+
// accepted here lands on every peer at once and the next rolling restart takes the whole cluster
|
|
1125
|
+
// down together (harper-pro#558). Boot-time writers are deliberately not gated the same way: config
|
|
1126
|
+
// that already exists has to stay bootable, so it is recovered at the point of use instead
|
|
1127
|
+
// (server/threads/threadHeapMemory.ts).
|
|
1128
|
+
function assertThreadHeapMemoryStartable(configFields) {
|
|
1129
|
+
for (const field in configFields) {
|
|
1130
|
+
const configParam = CONFIG_PARAM_MAP[field.toLowerCase()];
|
|
1131
|
+
let configured;
|
|
1132
|
+
if (configParam === CONFIG_PARAMS.THREADS_MAXHEAPMEMORY)
|
|
1133
|
+
configured = configFields[field];
|
|
1134
|
+
else if (configParam === CONFIG_PARAMS.THREADS)
|
|
1135
|
+
configured = readSectionHeapMemory(configFields[field]);
|
|
1136
|
+
else
|
|
1137
|
+
continue;
|
|
1138
|
+
const value = castConfigValue(CONFIG_PARAMS.THREADS_MAXHEAPMEMORY, configured);
|
|
1139
|
+
if (typeof value !== 'number' || (0, threadHeapMemory_ts_1.isStartableThreadHeapMemory)(value))
|
|
1140
|
+
continue;
|
|
1141
|
+
throw (0, hdbError_ts_1.handleHDBError)(new Error(), commonErrors_ts_1.HDB_ERROR_MSGS.CONFIG_VALIDATION(`'threads.maxHeapMemory' must be greater than or equal to ${hdbTerms.MIN_THREAD_HEAP_MEMORY_MB}`), commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
// A whole `threads` section reaches the same config key, and `threads` canonicalizes to itself
|
|
1145
|
+
// rather than to `threads_count`. It arrives either as an object or as the JSON string
|
|
1146
|
+
// castConfigValue parses, and flattenConfig lowercases every key on the way back out, so the nested
|
|
1147
|
+
// name has to be matched the same way the top-level one is.
|
|
1148
|
+
function readSectionHeapMemory(section) {
|
|
1149
|
+
const parsed = castConfigValue(CONFIG_PARAMS.THREADS, section);
|
|
1150
|
+
if (!hdbUtils.isObject(parsed))
|
|
1151
|
+
return undefined;
|
|
1152
|
+
for (const key in parsed)
|
|
1153
|
+
if (key.toLowerCase() === 'maxheapmemory')
|
|
1154
|
+
return parsed[key];
|
|
1155
|
+
}
|
|
950
1156
|
/**
|
|
951
1157
|
* Set Configuration - this function sets new configuration
|
|
952
1158
|
* @param setConfigJson
|
|
953
1159
|
|
|
954
1160
|
*/
|
|
955
1161
|
async function setConfiguration(setConfigJson) {
|
|
1162
|
+
// `hdb_auth_header` is the 4.x spelling of `hdbAuthHeader`, and `impersonate` is a generic
|
|
1163
|
+
// operation-body field (server/operationsServer.ts): control fields, never config params.
|
|
956
1164
|
// eslint-disable-next-line no-unused-vars
|
|
957
|
-
const { operation, hdb_user, hdbAuthHeader, replicated, ...configFields } = setConfigJson;
|
|
1165
|
+
const { operation, hdb_user, hdbAuthHeader, hdb_auth_header, impersonate, replicated, ...configFields } = setConfigJson;
|
|
958
1166
|
// Operation-control field, not a config param: enforce boolean (matching other
|
|
959
1167
|
// `replicated` surfaces, e.g. analyticsValidator) before any local write so a
|
|
960
1168
|
// malformed value like the string "false" — which is truthy — can't apply config
|
|
@@ -962,6 +1170,18 @@ async function setConfiguration(setConfigJson) {
|
|
|
962
1170
|
if (replicated !== undefined && typeof replicated !== 'boolean') {
|
|
963
1171
|
throw (0, hdbError_ts_1.handleHDBError)(new Error(), `'replicated' must be a boolean`, commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
|
|
964
1172
|
}
|
|
1173
|
+
const reservedComponentParams = findReservedComponentParams(configFields);
|
|
1174
|
+
if (reservedComponentParams.length > 0) {
|
|
1175
|
+
throw (0, hdbError_ts_1.handleHDBError)(new Error(), `Unable to update config, cannot configure a component whose name is reserved for Harper's own configuration section: ${describeUnrecognized(reservedComponentParams)}`, commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
|
|
1176
|
+
}
|
|
1177
|
+
// Before any local write: the writer skips names it cannot resolve, so a request mixing
|
|
1178
|
+
// recognized and unrecognized names would otherwise apply the recognized half and still report
|
|
1179
|
+
// success.
|
|
1180
|
+
const unrecognized = findUnrecognizedParams(configFields);
|
|
1181
|
+
if (unrecognized.length > 0) {
|
|
1182
|
+
throw (0, hdbError_ts_1.handleHDBError)(new Error(), `Unable to update config, unrecognized config parameter${unrecognized.length > 1 ? 's' : ''}: ${describeUnrecognized(unrecognized)}`, commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
|
|
1183
|
+
}
|
|
1184
|
+
assertThreadHeapMemoryStartable(configFields);
|
|
965
1185
|
try {
|
|
966
1186
|
updateConfigValue(undefined, undefined, configFields, true);
|
|
967
1187
|
if (replicated) {
|
|
@@ -1043,9 +1263,16 @@ function applyRuntimeEnvVarConfig(configDoc, configFilePath, options = {}) {
|
|
|
1043
1263
|
return;
|
|
1044
1264
|
// Convert to JSON for processing
|
|
1045
1265
|
const configObj = configDoc.toJSON();
|
|
1266
|
+
let saveEnvConfigState;
|
|
1267
|
+
let confirmEnvConfigState;
|
|
1268
|
+
let commitEnvConfigState;
|
|
1046
1269
|
try {
|
|
1047
1270
|
// Apply env vars with source tracking and drift detection
|
|
1048
|
-
(
|
|
1271
|
+
({
|
|
1272
|
+
saveState: saveEnvConfigState,
|
|
1273
|
+
confirmConfigWritten: confirmEnvConfigState,
|
|
1274
|
+
commitState: commitEnvConfigState,
|
|
1275
|
+
} = (0, harperConfigEnvVars_ts_1.prepareRuntimeEnvConfig)(configObj, rootPath, options));
|
|
1049
1276
|
// If securePort was set to the same value as port, auto-null port to avoid clashing
|
|
1050
1277
|
if (configObj.http?.port && configObj.http?.port === configObj.http?.securePort) {
|
|
1051
1278
|
configObj.http.port = null;
|
|
@@ -1067,17 +1294,47 @@ function applyRuntimeEnvVarConfig(configDoc, configFilePath, options = {}) {
|
|
|
1067
1294
|
harper_logger_ts_1.default.error(`Failed to apply runtime env config: ${error.message}`);
|
|
1068
1295
|
throw error;
|
|
1069
1296
|
}
|
|
1070
|
-
//
|
|
1297
|
+
// Install has no config file yet and no process to keep alive, so its snapshot write stays
|
|
1298
|
+
// mandatory - an install that never recorded originals should fail, not proceed.
|
|
1071
1299
|
if (!configFilePath) {
|
|
1300
|
+
commitEnvConfigState();
|
|
1072
1301
|
return;
|
|
1073
1302
|
}
|
|
1303
|
+
// Every worker thread runs initConfig and derives the same merged config, so letting them all
|
|
1304
|
+
// persist it means N threads racing over one pair of files for a result they already agree on.
|
|
1305
|
+
// The main thread owns the on-disk copy; a worker runs on the in-memory one.
|
|
1306
|
+
if (!node_worker_threads_1.isMainThread)
|
|
1307
|
+
return;
|
|
1074
1308
|
// Persist changes to file
|
|
1075
1309
|
try {
|
|
1076
1310
|
if (configDoc.errors?.length > 0) {
|
|
1077
1311
|
throw (0, hdbError_ts_1.handleHDBError)(new Error(), `Error parsing harperdb-config.yaml: ${configDoc.errors}`, commonErrors_ts_1.HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR);
|
|
1078
1312
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1313
|
+
// Stage, write the file, promote by rename: the confirmed state is the only record of the
|
|
1314
|
+
// file's pre-env values, so no write an exhausted volume can refuse may stand between it and
|
|
1315
|
+
// disk. See DESIGN.md, boot-path config persistence.
|
|
1316
|
+
let stateStaged = false;
|
|
1317
|
+
if (persistConfigDuringBoot(`${rootPath} env config state`, () => (stateStaged = saveEnvConfigState()))) {
|
|
1318
|
+
let configPersisted = false;
|
|
1319
|
+
let configRewritten = false;
|
|
1320
|
+
try {
|
|
1321
|
+
configPersisted = persistConfigDuringBoot(configFilePath, () => {
|
|
1322
|
+
configRewritten = atomicWriteFile(configFilePath, String(configDoc), { skipIfUnchanged: true });
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
finally {
|
|
1326
|
+
if (!configPersisted && stateStaged)
|
|
1327
|
+
(0, harperConfigEnvVars_ts_1.discardConfigState)(rootPath);
|
|
1328
|
+
}
|
|
1329
|
+
if (configPersisted) {
|
|
1330
|
+
if (stateStaged)
|
|
1331
|
+
confirmEnvConfigState();
|
|
1332
|
+
// Distinguished, because this is the line that answers "did something rewrite my config?"
|
|
1333
|
+
harper_logger_ts_1.default.debug(configRewritten
|
|
1334
|
+
? 'Config file updated with runtime env var values'
|
|
1335
|
+
: 'Config file already matched the runtime env var values');
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1081
1338
|
}
|
|
1082
1339
|
catch (error) {
|
|
1083
1340
|
harper_logger_ts_1.default.error(`Failed to write config file after applying runtime env vars: ${error.message}`);
|