fix: don't call stat on each file in dir (#2522)

* fix: decrease metering service gloabl rate of change check

* fix: don't call stat on each file in dir
This commit is contained in:
Daniel Salazar
2026-02-20 19:07:16 -08:00
committed by GitHub
parent d418976ee4
commit 3834571ab8
4 changed files with 19 additions and 37 deletions
@@ -28,7 +28,7 @@ export class MeteringService {
this.#eventService = eventService;
setInterval(() => {
this.#checkRateOfChange();
}, 1000 * 60 * 5); // check every 5 minutes
}, 1000 * 60 * 15); // check every 15 minutes
}
utilRecordUsageObject<T extends Record<string, number>>(trackedUsageObject: T, actor: Actor, modelPrefix: string, costsOverrides?: Partial<Record<keyof T, number>>) {
@@ -688,8 +688,8 @@ export class MeteringService {
return this.#kvStore.get({ key: `${METRICS_PREFIX}:lastGlobalUsageCheck` }) as Promise<{ total: number, timestamp: number } | null>;
});
if ( !lastChange || (now - lastChange.timestamp) > 4 * 60 * 1000 ) {
// only checked if more than 4 minutes from last check
if ( !lastChange || (now - lastChange.timestamp) > 14 * 60 * 1000 ) {
// only checked if more than 14 minutes from last check
const globalUsage = await this.getGlobalUsage();
const currTotal = globalUsage.total;
+6 -12
View File
@@ -121,7 +121,7 @@ async function UIItem (options) {
}
const item_id = window.global_element_id++;
let last_mousedown_ts = 999999999999999;
let last_mousedown_ts = Number.MAX_SAFE_INTEGER;
let rename_cancelled = false;
// set options defaults
@@ -139,15 +139,9 @@ async function UIItem (options) {
options.immutable = (options.immutable === false || options.immutable === 0 || options.immutable === undefined ? 0 : 1);
options.sort_container_after_append = (options.sort_container_after_append !== undefined ? options.sort_container_after_append : false);
const is_shared_with_me = (options.path !== `/${window.user.username}` && !options.path.startsWith(`/${window.user.username}/`));
let worker_url;
let is_worker;
if ( ! options.is_dir ) {
const stats = await puter.fs.stat({ path: options.path, returnWorkers: true });
is_worker = stats.workers !== undefined && stats.workers.length > 0;
if ( is_worker ) {
worker_url = stats.workers[0].address;
}
}
const workers = Array.isArray(options.workers) ? options.workers : [];
const is_worker = !options.is_dir && workers.length > 0;
const worker_url = is_worker ? workers[0].address : '';
let website_url = window.determine_website_url(options.path);
@@ -174,8 +168,8 @@ async function UIItem (options) {
data-website_url = "${website_url ? html_encode(website_url) : ''}"
data-immutable="${options.immutable}"
data-is_shortcut = "${options.is_shortcut}"
data-is_worker = "${is_worker !== undefined ? 1 : 0}"
data-worker_url = "${is_worker !== undefined ? worker_url : 0}"
data-is_worker = "${is_worker ? 1 : 0}"
data-worker_url = "${is_worker ? worker_url : 0}"
data-shortcut_to = "${html_encode(options.shortcut_to)}"
data-shortcut_to_path = "${html_encode(options.shortcut_to_path)}"
data-sortable = "${options.sortable ?? 'true'}"
@@ -36,15 +36,9 @@ const get_html_element_from_options = async function (options) {
options.immutable = (options.immutable === false || options.immutable === 0 || options.immutable === undefined ? 0 : 1);
options.sort_container_after_append = (options.sort_container_after_append !== undefined ? options.sort_container_after_append : false);
const is_shared_with_me = (options.path !== `/${window.user.username}` && !options.path.startsWith(`/${window.user.username}/`));
let worker_url;
let is_worker;
if ( ! options.is_dir ) {
const stats = await puter.fs.stat({ path: options.path, returnWorkers: true });
is_worker = stats.workers !== undefined && stats.workers.length > 0;;
if ( is_worker ) {
worker_url = stats.workers[0].address;
}
}
const workers = Array.isArray(options.workers) ? options.workers : [];
const is_worker = !options.is_dir && workers.length > 0;
const worker_url = is_worker ? workers[0].address : '';
let website_url = window.determine_website_url(options.path);
@@ -71,8 +65,8 @@ const get_html_element_from_options = async function (options) {
data-website_url = "${website_url ? html_encode(website_url) : ''}"
data-immutable="${options.immutable}"
data-is_shortcut = "${options.is_shortcut}"
data-is_worker = "${is_worker !== undefined ? 1 : 0}"
data-worker_url = "${is_worker !== undefined ? worker_url : 0}"
data-is_worker = "${is_worker ? 1 : 0}"
data-worker_url = "${is_worker ? worker_url : 0}"
data-shortcut_to = "${html_encode(options.shortcut_to)}"
data-shortcut_to_path = "${html_encode(options.shortcut_to_path)}"
data-sortable = "${options.sortable ?? 'true'}"
@@ -165,4 +159,4 @@ const get_html_element_from_options = async function (options) {
return h;
};
export default get_html_element_from_options;
export default get_html_element_from_options;
+4 -10
View File
@@ -113,8 +113,8 @@ const refresh_item_container = function (el_item_container, options) {
// remove all existing items
$(el_item_container).find('.item').removeItems();
// get items (skip subdomain fetching for faster response)
puter.fs.readdir({ path: container_path, consistency: options.consistency ?? 'eventual', no_subdomains: true }).then(async (fsentries) => {
// get items with subdomains/workers included to avoid per-item stat calls
puter.fs.readdir({ path: container_path, consistency: options.consistency ?? 'eventual' }).then(async (fsentries) => {
// Check if the same folder is still loading since el_item_container's
// data-path might have changed by other operations while waiting for the response to this `readdir`.
if ( $(el_item_container).attr('data-path') !== container_path )
@@ -204,6 +204,7 @@ const refresh_item_container = function (el_item_container, options) {
is_shortcut: fsentry.is_shortcut,
shortcut_to: fsentry.shortcut_to,
shortcut_to_path: fsentry.shortcut_to_path,
workers: fsentry.workers,
size: fsentry.size,
type: fsentry.type,
modified: fsentry.modified,
@@ -242,13 +243,6 @@ const refresh_item_container = function (el_item_container, options) {
$(el_item_container).attr('data-sort_by'),
$(el_item_container).attr('data-sort_order'));
// Fetch subdomains separately for directories and update UI
// Use the reusable function to update subdomains
// Note: This is fire-and-forget - it will update items asynchronously
window.updateSubdomainsForItems(fsentries, el_item_container).catch(err => {
console.warn('Failed to update subdomains for items:', err);
});
if ( options.fadeInItems ) {
$(el_item_container).animate({ 'opacity': '1' }, {
complete: () => {
@@ -299,4 +293,4 @@ const refresh_item_container = function (el_item_container, options) {
});
};
export default refresh_item_container;
export default refresh_item_container;