fix: reduce memory usage for monthly ZIP archive flow
Replace generated archive download response with FileResponse streaming so ZIP files are not fully loaded into process memory. Move monthly archive task output to a temporary file and upload that file to storage, and write invoice attachments into ZIP archives in chunks. Add Celery memory guard settings, a memory-aware base task hook, and periodic /tmp cleanup for prefixed archive files older than one day. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
# backend/core/celery.py
|
||||
|
||||
import os
|
||||
import gc
|
||||
import logging
|
||||
from celery import Celery
|
||||
from celery import Task
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Postavi Django settings modul
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
|
||||
@@ -11,5 +16,42 @@ app = Celery('core')
|
||||
# Koristi konfiguraciju iz settings.py s prefiksom 'CELERY_'
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||
|
||||
|
||||
def _rss_memory_mb():
|
||||
try:
|
||||
import resource
|
||||
|
||||
usage_kb = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
|
||||
# Na Linuxu je ru_maxrss u KiB.
|
||||
return round(float(usage_kb) / 1024.0, 2)
|
||||
except (ImportError, AttributeError, OSError, ValueError):
|
||||
return None
|
||||
|
||||
|
||||
class MemoryAwareTask(Task):
|
||||
abstract = True
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
gc.collect()
|
||||
return super().__call__(*args, **kwargs)
|
||||
|
||||
def after_return(self, status, retval, task_id, args, kwargs, einfo):
|
||||
memory_before_gc = _rss_memory_mb()
|
||||
gc.collect()
|
||||
memory_after_gc = _rss_memory_mb()
|
||||
if memory_before_gc is not None and memory_after_gc is not None:
|
||||
logger.info(
|
||||
"Task %s (%s) status=%s RSS prije/poslije GC: %.2fMB -> %.2fMB",
|
||||
self.name,
|
||||
task_id,
|
||||
status,
|
||||
memory_before_gc,
|
||||
memory_after_gc,
|
||||
)
|
||||
return super().after_return(status, retval, task_id, args, kwargs, einfo)
|
||||
|
||||
|
||||
app.Task = MemoryAwareTask
|
||||
|
||||
# Automatski pronalazi taskove u svim 'modules.*'
|
||||
app.autodiscover_tasks()
|
||||
Reference in New Issue
Block a user