velocious 1.0.691 → 1.0.692
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/README.md +1 -1
- package/build/background-jobs/store.js +61 -0
- package/build/configuration-types.js +1 -0
- package/build/database/drivers/base.js +54 -2
- package/build/database/drivers/mysql/index.js +23 -0
- package/build/database/drivers/mysql/query.js +1 -1
- package/build/src/background-jobs/store.d.ts +10 -0
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +55 -1
- package/build/src/configuration-types.d.ts +5 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +2 -1
- package/build/src/database/drivers/base.d.ts +21 -0
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +52 -3
- package/build/src/database/drivers/mysql/index.d.ts +9 -0
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +20 -1
- package/build/src/database/drivers/mysql/query.js +2 -2
- package/package.json +1 -1
- package/src/background-jobs/store.js +61 -0
- package/src/configuration-types.js +1 -0
- package/src/database/drivers/base.js +54 -2
- package/src/database/drivers/mysql/index.js +23 -0
- package/src/database/drivers/mysql/query.js +1 -1
|
@@ -183,6 +183,12 @@ const SCHEMA_INVALIDATION_SCAN_LIMIT = 8192
|
|
|
183
183
|
/** Maximum checkout-name characters inspected by retry diagnostics. */
|
|
184
184
|
const OPERATION_NAME_SCAN_LIMIT = 1024
|
|
185
185
|
const REDACTED_DIAGNOSTIC_LABEL = "[REDACTED]"
|
|
186
|
+
/** First backoff between retries of a schema-metadata read blocked by concurrent online DDL. */
|
|
187
|
+
const SCHEMA_METADATA_RETRY_INITIAL_DELAY_MS = 250
|
|
188
|
+
/** Largest backoff between retries of a schema-metadata read blocked by concurrent online DDL. */
|
|
189
|
+
const SCHEMA_METADATA_RETRY_MAX_DELAY_MS = 2000
|
|
190
|
+
/** Default bounded deadline for outlasting a concurrent online-DDL metadata skip. */
|
|
191
|
+
const SCHEMA_METADATA_RETRY_DEADLINE_MS = 60000
|
|
186
192
|
|
|
187
193
|
/**
|
|
188
194
|
* Builds a non-reversible, stable SQL fingerprint without retaining SQL text. Literal spelling is
|
|
@@ -777,6 +783,52 @@ export default class VelociousDatabaseDriversBase {
|
|
|
777
783
|
return this.getArgs().schemaCache !== false
|
|
778
784
|
}
|
|
779
785
|
|
|
786
|
+
/**
|
|
787
|
+
* Runs schema metadata retry deadline ms.
|
|
788
|
+
* @returns {number} - Bounded deadline for outlasting transient schema-metadata contention.
|
|
789
|
+
*/
|
|
790
|
+
_schemaMetadataRetryDeadlineMs() {
|
|
791
|
+
const configured = this.getArgs().schemaMetadataRetryDeadlineMs
|
|
792
|
+
|
|
793
|
+
return typeof configured === "number" ? configured : SCHEMA_METADATA_RETRY_DEADLINE_MS
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Whether an error raised by a schema-metadata read is transient contention that a bounded
|
|
798
|
+
* retry can outlast. Drivers override this for their own contention signatures; the default
|
|
799
|
+
* treats every failure as final so only drivers that prove the transient shape retry it.
|
|
800
|
+
* @param {unknown} _error - Error raised by a schema-metadata read.
|
|
801
|
+
* @returns {boolean} - Whether the read may be retried.
|
|
802
|
+
*/
|
|
803
|
+
_isTransientSchemaMetadataError(_error) {
|
|
804
|
+
return false
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Runs a schema-metadata read, retrying transient concurrent-DDL contention until the bounded
|
|
809
|
+
* deadline. Non-transient failures and exhausted deadlines propagate the original error.
|
|
810
|
+
* @template T
|
|
811
|
+
* @param {() => Promise<T>} callback - Cache-miss schema read.
|
|
812
|
+
* @returns {Promise<T>} - Resolves with the read result.
|
|
813
|
+
*/
|
|
814
|
+
async _withSchemaMetadataDdlRetry(callback) {
|
|
815
|
+
const deadlineMs = this._schemaMetadataRetryDeadlineMs()
|
|
816
|
+
const startedAt = Date.now()
|
|
817
|
+
let delayMs = SCHEMA_METADATA_RETRY_INITIAL_DELAY_MS
|
|
818
|
+
|
|
819
|
+
for (;;) {
|
|
820
|
+
try {
|
|
821
|
+
return await callback()
|
|
822
|
+
} catch (error) {
|
|
823
|
+
if (!this._isTransientSchemaMetadataError(error)) throw error
|
|
824
|
+
if (Date.now() - startedAt + delayMs > deadlineMs) throw error
|
|
825
|
+
|
|
826
|
+
await wait(delayMs)
|
|
827
|
+
delayMs = Math.min(delayMs * 2, SCHEMA_METADATA_RETRY_MAX_DELAY_MS)
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
780
832
|
/**
|
|
781
833
|
* Runs cached schema metadata.
|
|
782
834
|
* @template T
|
|
@@ -785,7 +837,7 @@ export default class VelociousDatabaseDriversBase {
|
|
|
785
837
|
* @returns {Promise<T>} - Resolves with the cached metadata.
|
|
786
838
|
*/
|
|
787
839
|
async _cachedSchemaMetadata(cacheKey, callback) {
|
|
788
|
-
if (!this._schemaCacheEnabled()) return await callback
|
|
840
|
+
if (!this._schemaCacheEnabled()) return await this._withSchemaMetadataDdlRetry(callback)
|
|
789
841
|
|
|
790
842
|
const existingPromise = this._schemaCache.get(cacheKey)
|
|
791
843
|
|
|
@@ -793,7 +845,7 @@ export default class VelociousDatabaseDriversBase {
|
|
|
793
845
|
return /** @type {T} */ (this._schemaCacheReturnValue(await existingPromise))
|
|
794
846
|
}
|
|
795
847
|
|
|
796
|
-
const promise = (async () => await callback
|
|
848
|
+
const promise = (async () => await this._withSchemaMetadataDdlRetry(callback))()
|
|
797
849
|
|
|
798
850
|
this._schemaCache.set(cacheKey, promise)
|
|
799
851
|
|
|
@@ -723,6 +723,29 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
723
723
|
return insert.toSql()
|
|
724
724
|
}
|
|
725
725
|
|
|
726
|
+
/**
|
|
727
|
+
* MariaDB skips information-schema/SHOW reads for a table whose definition is being modified
|
|
728
|
+
* by concurrent online DDL (ER_WARN_I_S_SKIPPED_TABLE). The build completes in seconds, so the
|
|
729
|
+
* skip is transient contention that the bounded schema-metadata retry can outlast. Query
|
|
730
|
+
* helpers wrap the driver error, so the code is searched through the cause chain.
|
|
731
|
+
* @param {unknown} error - Error raised by a schema-metadata read.
|
|
732
|
+
* @returns {boolean} - Whether the read hit concurrent-DDL metadata contention.
|
|
733
|
+
*/
|
|
734
|
+
_isTransientSchemaMetadataError(error) {
|
|
735
|
+
let currentError = /** @type {{code?: string, cause?: unknown} | undefined} */ (
|
|
736
|
+
/** @type {unknown} */ (error)
|
|
737
|
+
)
|
|
738
|
+
|
|
739
|
+
for (let depth = 0; depth < 5 && currentError; depth++) {
|
|
740
|
+
if (currentError.code === "ER_WARN_I_S_SKIPPED_TABLE") return true
|
|
741
|
+
currentError = /** @type {{code?: string, cause?: unknown} | undefined} */ (
|
|
742
|
+
/** @type {unknown} */ (currentError.cause)
|
|
743
|
+
)
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
return false
|
|
747
|
+
}
|
|
748
|
+
|
|
726
749
|
/**
|
|
727
750
|
* Runs get tables.
|
|
728
751
|
* @returns {Promise<Array<import("../base-table.js").default>>} - Resolves with the tables.
|
|
@@ -171,7 +171,7 @@ export default async function query(pool, sql, {signal} = {}) {
|
|
|
171
171
|
connection.release()
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
reject(new Error(`Query failed because of ${error}: ${sql}
|
|
174
|
+
reject(new Error(`Query failed because of ${error}: ${sql}`, {cause: error}))
|
|
175
175
|
|
|
176
176
|
return
|
|
177
177
|
}
|