Fix concurrent saves
This commit is contained in:
parent
c0a19c2a7e
commit
0c77cf2b40
|
@ -5,8 +5,8 @@ import {
|
||||||
processFormulas,
|
processFormulas,
|
||||||
} from "../../../utilities/rowProcessor"
|
} from "../../../utilities/rowProcessor"
|
||||||
import { FieldTypes, FormulaTypes } from "../../../constants"
|
import { FieldTypes, FormulaTypes } from "../../../constants"
|
||||||
import { context } from "@budibase/backend-core"
|
import { context, locks } from "@budibase/backend-core"
|
||||||
import { Table, Row } from "@budibase/types"
|
import { Table, Row, LockType, LockName } from "@budibase/types"
|
||||||
import * as linkRows from "../../../db/linkedRows"
|
import * as linkRows from "../../../db/linkedRows"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import isEqual from "lodash/isEqual"
|
import isEqual from "lodash/isEqual"
|
||||||
|
@ -149,12 +149,22 @@ export async function finaliseRow(
|
||||||
await db.put(table)
|
await db.put(table)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.status === 409) {
|
if (err.status === 409) {
|
||||||
const updatedTable = await sdk.tables.getTable(table._id!)
|
// Some conflicts with the autocolumns occurred, we need to refetch the table and recalculate
|
||||||
let response = processAutoColumn(null, updatedTable, row, {
|
await locks.doWithLock(
|
||||||
|
{
|
||||||
|
type: LockType.AUTO_EXTEND,
|
||||||
|
name: LockName.PROCESS_AUTO_COLUMNS,
|
||||||
|
resource: table._id,
|
||||||
|
},
|
||||||
|
async () => {
|
||||||
|
const latestTable = await sdk.tables.getTable(table._id!)
|
||||||
|
let response = processAutoColumn(null, latestTable, row, {
|
||||||
reprocessing: true,
|
reprocessing: true,
|
||||||
})
|
})
|
||||||
await db.put(response.table)
|
await db.put(response.table)
|
||||||
row = response.row
|
row = response.row
|
||||||
|
}
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,25 +189,32 @@ describe("sdk >> rows >> internal", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
await config.doInContext(config.appId, async () => {
|
await config.doInContext(config.appId, async () => {
|
||||||
for (const row of makeRows(30)) {
|
for (const row of makeRows(5)) {
|
||||||
await internalSdk.save(table._id!, row, config.user._id)
|
await internalSdk.save(table._id!, row, config.user._id)
|
||||||
}
|
}
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
makeRows(200).map(row =>
|
makeRows(10).map(row =>
|
||||||
internalSdk.save(table._id!, row, config.user._id)
|
internalSdk.save(table._id!, row, config.user._id)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
for (const row of makeRows(20)) {
|
for (const row of makeRows(5)) {
|
||||||
await internalSdk.save(table._id!, row, config.user._id)
|
await internalSdk.save(table._id!, row, config.user._id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const persistedRows = await config.getRows(table._id!)
|
const persistedRows = await config.getRows(table._id!)
|
||||||
expect(persistedRows).toHaveLength(250)
|
expect(persistedRows).toHaveLength(20)
|
||||||
|
expect(persistedRows).toEqual(
|
||||||
|
expect.arrayContaining(
|
||||||
|
Array.from({ length: 20 }).map((_, i) =>
|
||||||
|
expect.objectContaining({ id: i + 1 })
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
const persistedTable = await config.getTable(table._id)
|
const persistedTable = await config.getTable(table._id)
|
||||||
expect((table as any).schema.id.lastID).toBe(0)
|
expect((table as any).schema.id.lastID).toBe(0)
|
||||||
expect(persistedTable.schema.id.lastID).toBe(250)
|
expect(persistedTable.schema.id.lastID).toBe(20)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,6 +21,7 @@ export enum LockName {
|
||||||
PERSIST_WRITETHROUGH = "persist_writethrough",
|
PERSIST_WRITETHROUGH = "persist_writethrough",
|
||||||
QUOTA_USAGE_EVENT = "quota_usage_event",
|
QUOTA_USAGE_EVENT = "quota_usage_event",
|
||||||
APP_MIGRATION = "app_migrations",
|
APP_MIGRATION = "app_migrations",
|
||||||
|
PROCESS_AUTO_COLUMNS = "process_auto_columns",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LockOptions = {
|
export type LockOptions = {
|
||||||
|
|
Loading…
Reference in New Issue