tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
27
pulls
pipelines
add caching to flush operation
awarm.space
6 months ago
6fdcfd64
1d761288
+60
-11
1 changed file
expand all
collapse all
unified
split
src
replicache
cachedServerMutationContext.ts
+60
-11
src/replicache/cachedServerMutationContext.ts
···
168
168
return ctx;
169
169
};
170
170
let flush = async () => {
171
171
+
let flushStart = performance.now();
172
172
+
let timeInsertingEntities = 0;
173
173
+
let timeProcessingFactWrites = 0;
174
174
+
let timeTextMerging = 0;
175
175
+
let timeFactInserts = 0;
176
176
+
let timeDeletingEntities = 0;
177
177
+
let timeDeletingFacts = 0;
178
178
+
let timeCacheCleanup = 0;
179
179
+
180
180
+
// Insert entities
181
181
+
let entityInsertStart = performance.now();
171
182
if (entitiesCache.length > 0)
172
183
await tx
173
184
.insert(entities)
174
185
.values(entitiesCache.map((e) => ({ set: e.set, id: e.id })));
186
186
+
timeInsertingEntities = performance.now() - entityInsertStart;
187
187
+
188
188
+
// Process fact writes
189
189
+
let factWritesStart = performance.now();
175
190
let factWrites = writeCache.flatMap((f) =>
176
191
f.type === "del" ? [] : [f.fact],
177
192
);
···
179
194
for (let f of factWrites) {
180
195
let attribute = Attributes[f.attribute as Attribute];
181
196
let data = f.data;
197
197
+
198
198
+
// Text merging timing
199
199
+
let textMergeStart = performance.now();
182
200
if (attribute.type === "text" && attribute.cardinality === "one") {
183
201
let values = Object.values(
184
202
textAttributeWriteCache[`${f.entity}-${f.attribute}`] || {},
185
203
);
186
204
if (values.length > 0) {
187
205
let existingFact = await scanIndex.eav(f.entity, f.attribute);
188
188
-
if (existingFact[0]) values.push(existingFact[0].data.value);
189
189
-
let updateBytes = Y.mergeUpdatesV1(
190
190
-
values.map((v) => base64.toByteArray(v)),
191
191
-
);
192
192
-
data.value = base64.fromByteArray(updateBytes);
206
206
+
if (existingFact[0] && !values.includes(existingFact[0].data.value))
207
207
+
values.push(existingFact[0].data.value);
208
208
+
if (values.length > 1)
209
209
+
data.value = base64.fromByteArray(
210
210
+
Y.mergeUpdatesV1(values.map((v) => base64.toByteArray(v))),
211
211
+
);
193
212
}
194
213
}
214
214
+
timeTextMerging += performance.now() - textMergeStart;
195
215
196
196
-
try {
197
197
-
await tx
216
216
+
// Fact insert timing
217
217
+
let factInsertStart = performance.now();
218
218
+
await tx.transaction((tx2) =>
219
219
+
tx2
198
220
.insert(facts)
199
221
.values({
200
222
id: f.id,
···
205
227
.onConflictDoUpdate({
206
228
target: facts.id,
207
229
set: { data: driz.sql`excluded.data` },
208
208
-
});
209
209
-
} catch (e) {
210
210
-
console.log(`error on inserting fact: `, JSON.stringify(e));
211
211
-
}
230
230
+
})
231
231
+
.catch((e) =>
232
232
+
console.log(`error on inserting fact: `, JSON.stringify(e)),
233
233
+
),
234
234
+
);
235
235
+
timeFactInserts += performance.now() - factInsertStart;
212
236
}
213
237
}
238
238
+
timeProcessingFactWrites = performance.now() - factWritesStart;
239
239
+
240
240
+
// Delete entities
241
241
+
let entityDeleteStart = performance.now();
214
242
if (deleteEntitiesCache.length > 0)
215
243
await tx
216
244
.delete(entities)
217
245
.where(driz.inArray(entities.id, deleteEntitiesCache));
246
246
+
timeDeletingEntities = performance.now() - entityDeleteStart;
247
247
+
248
248
+
// Delete facts
249
249
+
let factDeleteStart = performance.now();
218
250
let factDeletes = writeCache.flatMap((f) =>
219
251
f.type === "put" ? [] : [f.fact.id],
220
252
);
···
235
267
await tx.delete(facts).where(driz.or(...conditions));
236
268
}
237
269
}
270
270
+
timeDeletingFacts = performance.now() - factDeleteStart;
238
271
272
272
+
// Cache cleanup
273
273
+
let cacheCleanupStart = performance.now();
239
274
writeCache = [];
240
275
eavCache.clear();
241
276
permissionsCache = {};
242
277
entitiesCache = [];
243
278
permissionsCache = {};
244
279
deleteEntitiesCache = [];
280
280
+
timeCacheCleanup = performance.now() - cacheCleanupStart;
281
281
+
282
282
+
let totalFlushTime = performance.now() - flushStart;
283
283
+
console.log(`
284
284
+
Flush Performance Breakdown (${totalFlushTime.toFixed(2)}ms):
285
285
+
==========================================
286
286
+
Entity Insertions (${entitiesCache.length} entities): ${timeInsertingEntities.toFixed(2)}ms
287
287
+
Fact Processing (${factWrites.length} facts): ${timeProcessingFactWrites.toFixed(2)}ms
288
288
+
- Text Merging: ${timeTextMerging.toFixed(2)}ms
289
289
+
- Fact Inserts (nested transactions): ${timeFactInserts.toFixed(2)}ms
290
290
+
Entity Deletions (${deleteEntitiesCache.length} entities): ${timeDeletingEntities.toFixed(2)}ms
291
291
+
Fact Deletions: ${timeDeletingFacts.toFixed(2)}ms
292
292
+
Cache Cleanup: ${timeCacheCleanup.toFixed(2)}ms
293
293
+
`);
245
294
};
246
295
247
296
return {