Merge remote-tracking branch 'origin/main' into eric/262A0_PUT-453

This commit is contained in:
Daniel Salazar
2026-02-19 16:45:10 -08:00
7 changed files with 51 additions and 12 deletions
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2024-present Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { redisClient } from './redisSingleton.js';
export const deleteRedisKeys = async (...keysInput: string[]) => {
const keys = keysInput
.map(key => key === null || key === undefined ? '' : String(key))
.filter(Boolean);
if ( keys.length === 0 ) {
return 0;
}
let deleted = 0;
for ( const key of new Set(keys) ) {
deleted += await redisClient.del(key);
}
return deleted;
};
@@ -20,6 +20,7 @@ const { origin_from_url } = require('../../util/urlutil');
const { DB_READ } = require('../../services/database/consts');
const BaseService = require('../../services/BaseService');
const { redisClient } = require('../../clients/redis/redisSingleton');
const { deleteRedisKeys } = require('../../clients/redis/deleteRedisKeys.js');
const { AppRedisCacheSpace } = require('./AppRedisCacheSpace.js');
// Currently leaks memory (not sure why yet, but icons are a factor)
@@ -796,7 +797,7 @@ class AppInformationService extends BaseService {
.filter(Boolean)
.map(ext => AppRedisCacheSpace.associationAppsKey(ext));
if ( associationKeys.length ) {
await redisClient.del(...associationKeys);
await deleteRedisKeys(associationKeys);
}
// remove from recent
@@ -17,6 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { redisClient } from '../../clients/redis/redisSingleton.js';
import { deleteRedisKeys } from '../../clients/redis/deleteRedisKeys.js';
const appFullNamespace = 'apps';
const appLiteNamespace = 'apps:lite';
@@ -101,7 +102,7 @@ export const AppRedisCacheSpace = {
keys.push(...AppRedisCacheSpace.statsKeys(app.uid));
}
if ( keys.length ) {
await redisClient.del(...keys);
await deleteRedisKeys(keys);
}
},
invalidateCachedAppName: async (name, { rawIconVariants = [true, false] } = {}) => {
@@ -111,10 +112,10 @@ export const AppRedisCacheSpace = {
value: name,
rawIcon,
}));
await redisClient.del(...keys);
await deleteRedisKeys(keys);
},
invalidateAppStats: async (uid) => {
if ( ! uid ) return;
await redisClient.del(...AppRedisCacheSpace.statsKeys(uid));
await deleteRedisKeys(AppRedisCacheSpace.statsKeys(uid));
},
};
};
@@ -1,7 +1,7 @@
import { v4 as uuidv4 } from 'uuid';
import APIError from '../../api/APIError.js';
import { redisClient } from '../../clients/redis/redisSingleton.js';
import { deleteRedisKeys } from '../../clients/redis/deleteRedisKeys.js';
import config from '../../config.js';
import { AppRedisCacheSpace } from '../apps/AppRedisCacheSpace.js';
import { NodeInternalIDSelector } from '../../filesystem/node/selectors.js';
@@ -1166,7 +1166,7 @@ export default class AppService extends BaseService {
if ( ! normalizedNew.length ) {
const affectedExtensions = new Set(normalizedOld);
if ( affectedExtensions.size ) {
await redisClient.del(...Array.from(affectedExtensions)
await deleteRedisKeys(Array.from(affectedExtensions)
.map(ext => AppRedisCacheSpace.associationAppsKey(ext)));
}
return;
@@ -1180,7 +1180,7 @@ export default class AppService extends BaseService {
const affectedExtensions = new Set([...normalizedOld, ...normalizedNew]);
if ( affectedExtensions.size ) {
await redisClient.del(...Array.from(affectedExtensions)
await deleteRedisKeys(Array.from(affectedExtensions)
.map(ext => AppRedisCacheSpace.associationAppsKey(ext)));
}
}
+2 -2
View File
@@ -18,7 +18,7 @@
*/
const APIError = require('../../api/APIError');
const { AppRedisCacheSpace } = require('../../modules/apps/AppRedisCacheSpace.js');
const { redisClient } = require('../../clients/redis/redisSingleton');
const { deleteRedisKeys } = require('../../clients/redis/deleteRedisKeys.js');
const config = require('../../config');
const { app_name_exists } = require('../../helpers');
const { AppUnderUserActorType } = require('../../services/auth/Actor');
@@ -181,7 +181,7 @@ class AppES extends BaseES {
...normalizedNewAssociations,
]);
if ( affectedAssociationExtensions.size ) {
await redisClient.del(...Array.from(affectedAssociationExtensions)
await deleteRedisKeys(Array.from(affectedAssociationExtensions)
.map(ext => AppRedisCacheSpace.associationAppsKey(ext)));
}
@@ -17,6 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { redisClient } from '../clients/redis/redisSingleton.js';
import { deleteRedisKeys } from '../clients/redis/deleteRedisKeys.js';
const userKeyPrefix = 'users';
const defaultUserIdProperties = ['username', 'uuid', 'email', 'id', 'referral_code'];
@@ -65,7 +66,7 @@ const UserRedisCacheSpace = {
invalidateUser: async (user, props = defaultUserIdProperties) => {
const keys = UserRedisCacheSpace.keysForUser(user, props);
if ( keys.length ) {
await redisClient.del(...keys);
await deleteRedisKeys(keys);
}
},
invalidateById: async (id, props = defaultUserIdProperties) => {
@@ -28,6 +28,7 @@ const { UserActorType, Actor, AppUnderUserActorType } = require('./Actor');
const { PERM_KEY_PREFIX, MANAGE_PERM_PREFIX } = require('./permissionConts.mjs');
const { PermissionUtil, PermissionExploder, PermissionImplicator, PermissionRewriter } = require('./permissionUtils.mjs');
const { spanify } = require('../../util/otelutil');
const { deleteRedisKeys } = require('../../clients/redis/deleteRedisKeys.js');
const { redisClient } = require('../../clients/redis/redisSingleton');
const { PermissionScanRedisCacheSpace } = require('./PermissionScanRedisCacheSpace.js');
const { Context } = require('../../util/context');
@@ -277,7 +278,7 @@ class PermissionService extends BaseService {
cursor = next_cursor;
if ( keys?.length ) toDelete.push(...keys);
} while ( cursor !== '0' );
if ( toDelete.length ) await redisClient.del(...toDelete);
if ( toDelete.length ) await deleteRedisKeys(toDelete);
}
async validateUserPerms ({ actor, permissions }) {