Skip to content

Commit 98a843c

Browse files
KyleAMathewswardpeet
andauthoredOct 20, 2021
fix(gatsby): use lmdb.removeSync so getNode can't return deleted nodes (#33554)
Co-authored-by: Ward Peeters <ward@coding-tech.com>
1 parent 4d8e40b commit 98a843c

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed
 

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

+34-13
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,15 +197,31 @@ function updateDataStore(action: ActionsUnion): void {
192197
break
193198
}
194199
case `CREATE_NODE`:
200+
case `DELETE_NODE`:
195201
case `ADD_FIELD_TO_NODE`:
196202
case `ADD_CHILD_NODE_TO_PARENT_NODE`:
197-
case `DELETE_NODE`:
198203
case `MATERIALIZE_PAGE_MODE`: {
199204
const dbs = getDatabases()
200-
lastOperationPromise = Promise.all([
205+
const operationPromise = Promise.all([
201206
updateNodes(dbs.nodes, action),
202207
updateNodesByType(dbs.nodesByType, action),
203208
])
209+
lastOperationPromise = operationPromise
210+
211+
// if create is used in the same transaction as delete we should remove it from cache
212+
if (action.type === `CREATE_NODE`) {
213+
preSyncDeletedNodeIdsCache.delete(action.payload.id)
214+
}
215+
216+
if (action.type === `DELETE_NODE` && action.payload?.id) {
217+
preSyncDeletedNodeIdsCache.add(action.payload.id)
218+
operationPromise.then(() => {
219+
// only clear if no other operations have been done in the meantime
220+
if (lastOperationPromise === operationPromise) {
221+
preSyncDeletedNodeIdsCache.clear()
222+
}
223+
})
224+
}
204225
}
205226
}
206227
}

‎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
case `MATERIALIZE_PAGE_MODE`: {

0 commit comments

Comments
 (0)
Please sign in to comment.