Skip to content

Commit cd16cca

Browse files
KyleAMathewsvladar
authored andcommitted
fix(gatsby): use lmdb.removeSync so getNode can't return deleted nodes (#33554)
Co-authored-by: Ward Peeters <[email protected]> (cherry picked from commit 98a843c) # Conflicts: # packages/gatsby/src/datastore/lmdb/lmdb-datastore.ts
1 parent c692e1f commit cd16cca

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

packages/gatsby/src/datastore/lmdb/lmdb-datastore.ts

+35-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RootDatabase, open } from "lmdb-store"
1+
import { RootDatabase, open, ArrayLikeIterable } from "lmdb-store"
22
// import { performance } from "perf_hooks"
33
import { ActionsUnion, IGatsbyNode } from "../../redux/types"
44
import { updateNodes } from "./updates/nodes"
@@ -27,6 +27,8 @@ const lmdbDatastore = {
2727
getNodesByType,
2828
}
2929

30+
const preSyncDeletedNodeIdsCache = new Set()
31+
3032
function getDefaultDbPath(): string {
3133
const dbFileName =
3234
process.env.NODE_ENV === `test`
@@ -122,10 +124,8 @@ function iterateNodes(): GatsbyIterable<IGatsbyNode> {
122124
return new GatsbyIterable(
123125
nodesDb
124126
.getKeys({ snapshot: false })
125-
.map(
126-
nodeId => (typeof nodeId === `string` ? getNode(nodeId) : undefined)!
127-
)
128-
.filter(Boolean)
127+
.map(nodeId => (typeof nodeId === `string` ? getNode(nodeId) : undefined))
128+
.filter(Boolean) as ArrayLikeIterable<IGatsbyNode>
129129
)
130130
}
131131

@@ -134,13 +134,16 @@ function iterateNodesByType(type: string): GatsbyIterable<IGatsbyNode> {
134134
return new GatsbyIterable(
135135
nodesByType
136136
.getValues(type)
137-
.map(nodeId => getNode(nodeId)!)
138-
.filter(Boolean)
137+
.map(nodeId => getNode(nodeId))
138+
.filter(Boolean) as ArrayLikeIterable<IGatsbyNode>
139139
)
140140
}
141141

142142
function getNode(id: string): IGatsbyNode | undefined {
143-
if (!id) return undefined
143+
if (!id || preSyncDeletedNodeIdsCache.has(id)) {
144+
return undefined
145+
}
146+
144147
const { nodes } = getDatabases()
145148
return nodes.get(id)
146149
}
@@ -151,9 +154,11 @@ function getTypes(): Array<string> {
151154

152155
function countNodes(typeName?: string): number {
153156
if (!typeName) {
154-
const stats = getDatabases().nodes.getStats()
155-
// @ts-ignore
156-
return Number(stats.entryCount || 0) // FIXME: add -1 when restoring shared structures key
157+
const stats = getDatabases().nodes.getStats() as { entryCount: number }
158+
return Math.max(
159+
Number(stats.entryCount) - preSyncDeletedNodeIdsCache.size,
160+
0
161+
) // FIXME: add -1 when restoring shared structures key
157162
}
158163

159164
const { nodesByType } = getDatabases()
@@ -192,14 +197,30 @@ function updateDataStore(action: ActionsUnion): void {
192197
break
193198
}
194199
case `CREATE_NODE`:
200+
case `DELETE_NODE`:
195201
case `ADD_FIELD_TO_NODE`:
196-
case `ADD_CHILD_NODE_TO_PARENT_NODE`:
197-
case `DELETE_NODE`: {
202+
case `ADD_CHILD_NODE_TO_PARENT_NODE`: {
198203
const dbs = getDatabases()
199-
lastOperationPromise = Promise.all([
204+
const operationPromise = Promise.all([
200205
updateNodes(dbs.nodes, action),
201206
updateNodesByType(dbs.nodesByType, action),
202207
])
208+
lastOperationPromise = operationPromise
209+
210+
// if create is used in the same transaction as delete we should remove it from cache
211+
if (action.type === `CREATE_NODE`) {
212+
preSyncDeletedNodeIdsCache.delete(action.payload.id)
213+
}
214+
215+
if (action.type === `DELETE_NODE` && action.payload?.id) {
216+
preSyncDeletedNodeIdsCache.add(action.payload.id)
217+
operationPromise.then(() => {
218+
// only clear if no other operations have been done in the meantime
219+
if (lastOperationPromise === operationPromise) {
220+
preSyncDeletedNodeIdsCache.clear()
221+
}
222+
})
223+
}
203224
}
204225
}
205226
}

packages/gatsby/src/datastore/lmdb/updates/nodes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export function updateNodes(
1717
if (action.payload) {
1818
return nodesDb.remove(action.payload.id)
1919
}
20+
2021
return false
2122
}
2223
}

0 commit comments

Comments
 (0)