Refactor logging and formatting

Improved code readability
This commit is contained in:
Dariusz L
2025-06-27 05:32:11 +02:00
parent be4fae2964
commit 83ce890ef4
16 changed files with 241 additions and 363 deletions

View File

@@ -6,19 +6,14 @@ const log = createModuleLogger('ImageReferenceManager');
export class ImageReferenceManager {
constructor(canvas) {
this.canvas = canvas;
this.imageReferences = new Map(); // imageId -> count
this.imageLastUsed = new Map(); // imageId -> timestamp
this.gcInterval = 5 * 60 * 1000; // 5 minut (nieużywane)
this.maxAge = 30 * 60 * 1000; // 30 minut bez użycia
this.imageReferences = new Map();
this.imageLastUsed = new Map();
this.gcInterval = 5 * 60 * 1000;
this.maxAge = 30 * 60 * 1000;
this.gcTimer = null;
this.isGcRunning = false;
// Licznik operacji dla automatycznego GC
this.operationCount = 0;
this.operationThreshold = 500; // Uruchom GC po 500 operacjach
// Nie uruchamiamy automatycznego GC na czasie
// this.startGarbageCollection();
this.operationThreshold = 500;
}
/**
@@ -28,11 +23,11 @@ export class ImageReferenceManager {
if (this.gcTimer) {
clearInterval(this.gcTimer);
}
this.gcTimer = setInterval(() => {
this.performGarbageCollection();
}, this.gcInterval);
log.info("Garbage collection started with interval:", this.gcInterval / 1000, "seconds");
}
@@ -53,11 +48,11 @@ export class ImageReferenceManager {
*/
addReference(imageId) {
if (!imageId) return;
const currentCount = this.imageReferences.get(imageId) || 0;
this.imageReferences.set(imageId, currentCount + 1);
this.imageLastUsed.set(imageId, Date.now());
log.debug(`Added reference to image ${imageId}, count: ${currentCount + 1}`);
}
@@ -67,7 +62,7 @@ export class ImageReferenceManager {
*/
removeReference(imageId) {
if (!imageId) return;
const currentCount = this.imageReferences.get(imageId) || 0;
if (currentCount <= 1) {
this.imageReferences.delete(imageId);
@@ -83,18 +78,12 @@ export class ImageReferenceManager {
*/
updateReferences() {
log.debug("Updating image references...");
// Wyczyść stare referencje
this.imageReferences.clear();
// Zbierz wszystkie używane imageId
const usedImageIds = this.collectAllUsedImageIds();
// Dodaj referencje dla wszystkich używanych obrazów
usedImageIds.forEach(imageId => {
this.addReference(imageId);
});
log.info(`Updated references for ${usedImageIds.size} unique images`);
}
@@ -104,15 +93,11 @@ export class ImageReferenceManager {
*/
collectAllUsedImageIds() {
const usedImageIds = new Set();
// 1. Aktualne warstwy
this.canvas.layers.forEach(layer => {
if (layer.imageId) {
usedImageIds.add(layer.imageId);
}
});
// 2. Historia undo
if (this.canvas.canvasState && this.canvas.canvasState.layersUndoStack) {
this.canvas.canvasState.layersUndoStack.forEach(layersState => {
layersState.forEach(layer => {
@@ -122,8 +107,6 @@ export class ImageReferenceManager {
});
});
}
// 3. Historia redo
if (this.canvas.canvasState && this.canvas.canvasState.layersRedoStack) {
this.canvas.canvasState.layersRedoStack.forEach(layersState => {
layersState.forEach(layer => {
@@ -133,7 +116,7 @@ export class ImageReferenceManager {
});
});
}
log.debug(`Collected ${usedImageIds.size} used image IDs`);
return usedImageIds;
}
@@ -145,26 +128,22 @@ export class ImageReferenceManager {
*/
async findUnusedImages(usedImageIds) {
try {
// Pobierz wszystkie imageId z bazy danych
const allImageIds = await getAllImageIds();
const unusedImages = [];
const now = Date.now();
for (const imageId of allImageIds) {
// Sprawdź czy obraz nie jest używany
if (!usedImageIds.has(imageId)) {
const lastUsed = this.imageLastUsed.get(imageId) || 0;
const age = now - lastUsed;
// Usuń tylko stare obrazy (grace period)
if (age > this.maxAge) {
unusedImages.push(imageId);
} else {
log.debug(`Image ${imageId} is unused but too young (age: ${Math.round(age/1000)}s)`);
log.debug(`Image ${imageId} is unused but too young (age: ${Math.round(age / 1000)}s)`);
}
}
}
log.debug(`Found ${unusedImages.length} unused images ready for cleanup`);
return unusedImages;
} catch (error) {
@@ -182,34 +161,29 @@ export class ImageReferenceManager {
log.debug("No unused images to cleanup");
return;
}
log.info(`Starting cleanup of ${unusedImages.length} unused images`);
let cleanedCount = 0;
let errorCount = 0;
for (const imageId of unusedImages) {
try {
// Usuń z bazy danych
await removeImage(imageId);
// Usuń z cache
if (this.canvas.imageCache && this.canvas.imageCache.has(imageId)) {
this.canvas.imageCache.delete(imageId);
}
// Usuń z tracking
this.imageReferences.delete(imageId);
this.imageLastUsed.delete(imageId);
cleanedCount++;
log.debug(`Cleaned up image: ${imageId}`);
} catch (error) {
errorCount++;
log.error(`Error cleaning up image ${imageId}:`, error);
}
}
log.info(`Garbage collection completed: ${cleanedCount} images cleaned, ${errorCount} errors`);
}
@@ -221,23 +195,16 @@ export class ImageReferenceManager {
log.debug("Garbage collection already running, skipping");
return;
}
this.isGcRunning = true;
log.info("Starting garbage collection...");
try {
// 1. Aktualizuj referencje
this.updateReferences();
// 2. Zbierz wszystkie używane imageId
const usedImageIds = this.collectAllUsedImageIds();
// 3. Znajdź nieużywane obrazy
const unusedImages = await this.findUnusedImages(usedImageIds);
// 4. Wyczyść nieużywane obrazy
await this.cleanupUnusedImages(unusedImages);
} catch (error) {
log.error("Error during garbage collection:", error);
} finally {
@@ -251,11 +218,10 @@ export class ImageReferenceManager {
incrementOperationCount() {
this.operationCount++;
log.debug(`Operation count: ${this.operationCount}/${this.operationThreshold}`);
if (this.operationCount >= this.operationThreshold) {
log.info(`Operation threshold reached (${this.operationThreshold}), triggering garbage collection`);
this.operationCount = 0; // Reset counter
// Uruchom GC asynchronicznie, żeby nie blokować operacji
this.operationCount = 0;
setTimeout(() => {
this.performGarbageCollection();
}, 100);