mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-23 21:56:57 +00:00
fix: remove recommended app caching in favour of stronger caching at app fetch layer (#2748)
This commit is contained in:
@@ -118,6 +118,6 @@ export const setRedisCacheValue = async (
|
||||
if ( ttlSeconds ) {
|
||||
await redisClient.set(key, value, 'EX', ttlSeconds);
|
||||
} else {
|
||||
await redisClient.set(key, value);
|
||||
await redisClient.set(key, value, 'EX', 60 * 10); // default to 10 min if no ttl provided
|
||||
}
|
||||
};
|
||||
|
||||
@@ -364,7 +364,7 @@ export async function get_app (options) {
|
||||
const cacheApp = async (app) => {
|
||||
if ( ! app ) return;
|
||||
AppRedisCacheSpace.setCachedApp(app, {
|
||||
ttlSeconds: 30,
|
||||
ttlSeconds: 300,
|
||||
});
|
||||
};
|
||||
const isDecoratedAppCacheEntry = (app) => (
|
||||
@@ -550,7 +550,7 @@ export const get_apps = spanify('get_apps', async (specifiers, options = {}) =>
|
||||
const cacheApp = async (app) => {
|
||||
if ( ! app ) return;
|
||||
AppRedisCacheSpace.setCachedApp(app, {
|
||||
ttlSeconds: 60,
|
||||
ttlSeconds: 300,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ export const AppRedisCacheSpace = {
|
||||
if ( ! app ) return;
|
||||
const serialized = JSON.stringify(app);
|
||||
const writes = AppRedisCacheSpace.keysForApp(app)
|
||||
.map(key => setKey(key, serialized, { ttlSeconds }));
|
||||
.map(key => setKey(key, serialized, { ttlSeconds: ttlSeconds || 60 }));
|
||||
if ( writes.length ) {
|
||||
await Promise.all(writes);
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
export const RecommendedAppsRedisCacheSpace = {
|
||||
key: ({ iconSize } = {}) => `global:recommended-apps${iconSize ? `:icon-size:${iconSize}` : ''}`,
|
||||
};
|
||||
@@ -17,15 +17,11 @@
|
||||
* 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';
|
||||
import { setRedisCacheValue } from '../../clients/redis/cacheUpdate.js';
|
||||
import { get_apps } from '../../helpers.js';
|
||||
import BaseService from '../../services/BaseService.js';
|
||||
import { RecommendedAppsRedisCacheSpace } from './RecommendedAppsRedisCacheSpace.js';
|
||||
import { BaseService } from '../../services/BaseService.js';
|
||||
|
||||
export default class RecommendedAppsService extends BaseService {
|
||||
static APP_NAMES = [
|
||||
appNames = new Set([
|
||||
'app-center',
|
||||
'dev-center',
|
||||
'editor',
|
||||
@@ -44,49 +40,13 @@ export default class RecommendedAppsService extends BaseService {
|
||||
'galaxy-troops',
|
||||
'blend-fruits',
|
||||
'traffic-tap-puzzle',
|
||||
];
|
||||
|
||||
_construct () {
|
||||
this.app_names = new Set(RecommendedAppsService.APP_NAMES);
|
||||
}
|
||||
|
||||
'__on_boot.consolidation' () {
|
||||
const svc_appIcon = this.services.get('app-icon');
|
||||
const svc_event = this.services.get('event');
|
||||
svc_event.on('apps.invalidate', async (_, { app }) => {
|
||||
const sizes = svc_appIcon.getSizes();
|
||||
|
||||
// If it's a single-app invalidation, only invalidate if the
|
||||
// app is in the list of recommended apps
|
||||
if ( app ) {
|
||||
const name = app.name;
|
||||
if ( ! this.app_names.has(name) ) return;
|
||||
}
|
||||
|
||||
const keys = [RecommendedAppsRedisCacheSpace.key()];
|
||||
for ( const size of sizes ) {
|
||||
const key = RecommendedAppsRedisCacheSpace.key({ iconSize: size });
|
||||
keys.push(key);
|
||||
}
|
||||
await deleteRedisKeys(keys);
|
||||
});
|
||||
}
|
||||
]);
|
||||
|
||||
async get_recommended_apps ({ icon_size: iconSize }) {
|
||||
const recommendedCacheKey = RecommendedAppsRedisCacheSpace.key({ iconSize });
|
||||
|
||||
const cachedRecommended = await redisClient.get(recommendedCacheKey);
|
||||
if ( cachedRecommended ) {
|
||||
try {
|
||||
return JSON.parse(cachedRecommended);
|
||||
} catch (e) {
|
||||
// no op cache is in an invalid state
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare each app for returning to user by only returning the necessary fields
|
||||
// and adding them to the retobj array
|
||||
let recommended = (await get_apps(Array.from(this.app_names).map(name => ({ name })))).filter(app => !!app).map(app => {
|
||||
let recommended = (await get_apps(Array.from(this.appNames).map(name => ({ name })))).filter(app => !!app).map(app => {
|
||||
return {
|
||||
uuid: app.uid,
|
||||
name: app.name,
|
||||
@@ -108,10 +68,6 @@ export default class RecommendedAppsService extends BaseService {
|
||||
});
|
||||
}
|
||||
|
||||
await setRedisCacheValue(recommendedCacheKey, JSON.stringify(recommended), {
|
||||
eventData: recommended,
|
||||
});
|
||||
|
||||
return recommended;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user