mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-12 20:40:52 +00:00
fix: batch app info referral (#2146)
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test-backend (20.x) (push) Has been cancelled
test / test-backend (22.x) (push) Has been cancelled
test / API tests (node env, api-test) (22.x) (push) Has been cancelled
test / puterjs (node env, vitest) (22.x) (push) Has been cancelled
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test-backend (20.x) (push) Has been cancelled
test / test-backend (22.x) (push) Has been cancelled
test / API tests (node env, api-test) (22.x) (push) Has been cancelled
test / puterjs (node env, vitest) (22.x) (push) Has been cancelled
This commit is contained in:
@@ -22,6 +22,7 @@ const { MINUTE } = require('@heyputer/putility').libs.time;
|
||||
const { origin_from_url } = require('../../util/urlutil');
|
||||
const { DB_READ } = require('../../services/database/consts');
|
||||
const BaseService = require('../../services/BaseService');
|
||||
const { kv } = require('../../util/kvSingleton');
|
||||
|
||||
// Currently leaks memory (not sure why yet, but icons are a factor)
|
||||
const ENABLE_REFRESH_APP_CACHE = false;
|
||||
@@ -574,12 +575,8 @@ class AppInformationService extends BaseService {
|
||||
]);
|
||||
|
||||
// Build maps for quick lookup
|
||||
const openCountMap = new Map(
|
||||
openCounts.map(row => [row.app_uid, row.open_count])
|
||||
);
|
||||
const userCountMap = new Map(
|
||||
userCounts.map(row => [row.app_uid, row.user_count])
|
||||
);
|
||||
const openCountMap = new Map(openCounts.map(row => [row.app_uid, row.open_count]));
|
||||
const userCountMap = new Map(userCounts.map(row => [row.app_uid, row.user_count]));
|
||||
|
||||
// Get all app UIDs and update the cache
|
||||
const apps = await db.read('SELECT uid FROM apps');
|
||||
@@ -612,27 +609,64 @@ class AppInformationService extends BaseService {
|
||||
|
||||
const apps = await db.read('SELECT uid, index_url FROM apps');
|
||||
|
||||
// First, build a map of valid app origins to UIDs
|
||||
const validApps = [];
|
||||
const svc_auth = this.services.get('auth');
|
||||
|
||||
for ( const app of apps ) {
|
||||
const origin = origin_from_url(app.index_url);
|
||||
|
||||
// only count the referral if the origin hashes to the app's uid
|
||||
const svc_auth = this.services.get('auth');
|
||||
let expected_uid;
|
||||
try {
|
||||
expected_uid = await svc_auth.app_uid_from_origin(origin);
|
||||
} catch (e) {
|
||||
// This happens if the app origin isn't valid
|
||||
// This happens if the app origin isn't valid
|
||||
continue;
|
||||
}
|
||||
if ( expected_uid !== app.uid ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const key_referral_count = `apps:referral_count:uid:${app.uid}`;
|
||||
const { referral_count } = (await db.read('SELECT COUNT(id) AS referral_count FROM user WHERE referrer LIKE ?',
|
||||
[`${origin }%`]))[0];
|
||||
validApps.push({ uid: app.uid, origin });
|
||||
}
|
||||
|
||||
kv.set(key_referral_count, referral_count);
|
||||
if ( validApps.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a single query to get all referral counts
|
||||
const likeConditions = validApps.map(() => 'referrer LIKE ?').join(' OR ');
|
||||
const queryParams = validApps.map(app => `${app.origin}%`);
|
||||
|
||||
const referralResults = await db.read(`
|
||||
SELECT
|
||||
referrer,
|
||||
COUNT(id) as referral_count
|
||||
FROM user
|
||||
WHERE ${likeConditions}
|
||||
GROUP BY referrer
|
||||
`, queryParams);
|
||||
|
||||
// Create a map to store referral counts by origin
|
||||
const referralMap = new Map();
|
||||
|
||||
for ( const result of referralResults ) {
|
||||
// Find which app this referrer belongs to
|
||||
for ( const app of validApps ) {
|
||||
if ( result.referrer.startsWith(app.origin) ) {
|
||||
const currentCount = referralMap.get(app.uid) || 0;
|
||||
referralMap.set(app.uid, currentCount + parseInt(result.referral_count));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update cache with results
|
||||
for ( const app of validApps ) {
|
||||
const key_referral_count = `apps:referral_count:uid:${app.uid}`;
|
||||
const count = referralMap.get(app.uid) || 0;
|
||||
kv.set(key_referral_count, count);
|
||||
}
|
||||
|
||||
this.log.info('DONE refresh app stat referrals');
|
||||
@@ -786,16 +820,13 @@ class AppInformationService extends BaseService {
|
||||
period = currentDate.toISOString().slice(0, 10);
|
||||
currentDate.setDate(currentDate.getDate() + 1);
|
||||
break;
|
||||
case 'week':
|
||||
case 'week': {
|
||||
// Get the ISO week number
|
||||
// TODO: Fix this use of `getWeekNumber`, which doesn't exist.
|
||||
// I was not able to invoke this branch due to other
|
||||
// blockers when testing locally so I'm leaving this as-is
|
||||
// because I can't test for regressions.
|
||||
const weekNum = String(getWeekNumber(currentDate)).padStart(2, '0');
|
||||
const weekNum = String(this.getWeekNumber(currentDate)).padStart(2, '0');
|
||||
period = `${currentDate.getFullYear()}-${weekNum}`;
|
||||
currentDate.setDate(currentDate.getDate() + 7);
|
||||
break;
|
||||
}
|
||||
case 'month':
|
||||
period = currentDate.toISOString().slice(0, 7);
|
||||
currentDate.setMonth(currentDate.getMonth() + 1);
|
||||
@@ -838,10 +869,11 @@ class AppInformationService extends BaseService {
|
||||
case 'day':
|
||||
period = item.period.toISOString().slice(0, 10);
|
||||
break;
|
||||
case 'week':
|
||||
case 'week': {
|
||||
const weekNum = String(this.getWeekNumber(item.period)).padStart(2, '0');
|
||||
period = `${item.period.getFullYear()}-${weekNum}`;
|
||||
break;
|
||||
}
|
||||
case 'month':
|
||||
period = item.period.toISOString().slice(0, 7);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user