more nuanced cache invalidation strategy with logging enabled by default

This commit is contained in:
Nariman Jelveh
2025-09-28 20:35:51 -07:00
parent a965df0cc0
commit 7382264648
4 changed files with 65 additions and 20 deletions
+61 -14
View File
@@ -25,6 +25,8 @@ import { AdvancedBase } from '../../../../putility/index.js';
import FSItem from '../FSItem.js';
import deleteFSEntry from './operations/deleteFSEntry.js';
import getReadURL from './operations/getReadUrl.js';
import path from "../../lib/path.js";
export class PuterJSFileSystemModule extends AdvancedBase {
@@ -113,21 +115,50 @@ export class PuterJSFileSystemModule extends AdvancedBase {
}
bindSocketEvents() {
this.socket.on('cache.updated', (msg) => {
// check original_client_socket_id and if it matches this.socket.id, don't post update
if (msg.original_client_socket_id !== this.socket.id) {
this.invalidateCache();
// this.socket.on('cache.updated', (msg) => {
// // check original_client_socket_id and if it matches this.socket.id, don't post update
// if (msg.original_client_socket_id !== this.socket.id) {
// this.invalidateCache();
// }
// });
this.socket.on('item.renamed', (item) => {
// check original_client_socket_id and if it matches this.socket.id, don't invalidate cache
if (item.original_client_socket_id !== this.socket.id) {
this.invalidateCache(item);
}
});
// item.renamed is triggered when a file is renamed, this is a quirk since right now cache.updated is not triggered when a file is renamed!
this.socket.on('item.renamed', (item) => {
// check original_client_socket_id and if it matches this.socket.id, don't post update
this.socket.on('item.deleted', (item) => {
// check original_client_socket_id and if it matches this.socket.id, don't invalidate cache
if (item.original_client_socket_id !== this.socket.id) {
this.invalidateCache();
this.invalidateCache(item);
}
});
this.socket.on('item.added', (item) => {
// check original_client_socket_id and if it matches this.socket.id, don't invalidate cache
if (item.original_client_socket_id !== this.socket.id) {
this.invalidateCache(item);
}
});
this.socket.on('item.updated', (item) => {
// check original_client_socket_id and if it matches this.socket.id, don't invalidate cache
if (item.original_client_socket_id !== this.socket.id) {
this.invalidateCache(item);
}
});
this.socket.on('item.moved', (item) => {
// check original_client_socket_id and if it matches this.socket.id, don't invalidate cache
if (item.original_client_socket_id !== this.socket.id) {
this.invalidateCache(item);
}
});
this.socket.on('connect', () => {
if ( puter.debugMode )
{
@@ -218,15 +249,31 @@ export class PuterJSFileSystemModule extends AdvancedBase {
* @memberof PuterJSFileSystemModule
* @returns {void}
*/
invalidateCache() {
// Action: Flush local cache
puter._cache.flushall();
console.log('invalidateCache triggered, cache flushed');
invalidateCache(item) {
// Action: Update last valid time
//
// Set to 0, which means the cache is not up to date.
localStorage.setItem(LAST_VALID_TS, '0');
// Action: Update cache for the item
if(item?.path){
console.log('invalidated cache for item:', item.path);
// update cache for the item
puter._cache.set('item:' + item.path, item);
// if item is a folder, invalidate the readdir cache for the folder
if(item.is_dir){
puter._cache.del('readdir:' + item.path);
console.log('⮑ invalidated its readdir:', item.path);
}
// invalidate parent folder cache
puter._cache.del('readdir:' + path.dirname(item.path));
console.log('⮑ invalidated its parent readdir:', path.dirname(item.path));
}else{
puter._cache.flushall();
console.log('invalidated cache for all items');
}
}
/**
@@ -54,7 +54,7 @@ const mkdir = function (...args) {
create_missing_parents: (options.recursive || options.createMissingParents) ?? false,
}));
this.invalidateCache();
this.invalidateCache(options.path);
})
}
@@ -31,8 +31,6 @@ const readdir = async function (...args) {
let cacheKey;
if(options.path){
cacheKey = 'readdir:' + options.path;
}else if(options.uid){
cacheKey = 'readdir:' + options.uid;
}
if(options.consistency === 'eventual'){
@@ -64,7 +62,7 @@ const readdir = async function (...args) {
const resultSize = JSON.stringify(result).length;
// Cache the result if it's not bigger than MAX_CACHE_SIZE
const MAX_CACHE_SIZE = 20 * 1024 * 1024;
const MAX_CACHE_SIZE = 100 * 1024 * 1024;
if(resultSize <= MAX_CACHE_SIZE){
// UPSERT the cache
@@ -73,7 +71,6 @@ const readdir = async function (...args) {
// set each individual item's cache
for(const item of result){
await puter._cache.set('item:' + item.id, item);
await puter._cache.set('item:' + item.path, item);
}
@@ -47,11 +47,12 @@ const rename = function (...args) {
// If dirPath is not provided or it's not starting with a slash, it means it's a relative path
// in that case, we need to prepend the app's root directory to it
dataToSend.path = getAbsolutePathForApp(options.path);
this.invalidateCache(dataToSend.path);
}
xhr.send(JSON.stringify(dataToSend));
this.invalidateCache();
})
}