mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Backup task fixes (#4307)
* Ensure 'retry' is always greater than timeout * Adds setting for controlling how many days between automated backups * Adds configuration option for max_attempts * Update for daily backup task - Prevent backup attempts from ocurring too frequently - Add setting for controlling how many days between backups * Exit early
This commit is contained in:
parent
a10b8f2e47
commit
9e6466b910
@ -615,14 +615,16 @@ else:
|
||||
},
|
||||
}
|
||||
|
||||
_q_worker_timeout = int(get_setting('INVENTREE_BACKGROUND_TIMEOUT', 'background.timeout', 90))
|
||||
|
||||
# django-q background worker configuration
|
||||
Q_CLUSTER = {
|
||||
'name': 'InvenTree',
|
||||
'label': 'Background Tasks',
|
||||
'workers': int(get_setting('INVENTREE_BACKGROUND_WORKERS', 'background.workers', 4)),
|
||||
'timeout': int(get_setting('INVENTREE_BACKGROUND_TIMEOUT', 'background.timeout', 90)),
|
||||
'retry': 120,
|
||||
'max_attempts': 5,
|
||||
'timeout': _q_worker_timeout,
|
||||
'retry': min(120, _q_worker_timeout + 30),
|
||||
'max_attempts': int(get_setting('INVENTREE_BACKGROUND_MAX_ATTEMPTS', 'background.max_attempts', 5)),
|
||||
'queue_limit': 50,
|
||||
'catch_up': False,
|
||||
'bulk': 10,
|
||||
|
@ -3,10 +3,12 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
import warnings
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Callable, List
|
||||
|
||||
from django.conf import settings
|
||||
@ -428,9 +430,66 @@ def run_backup():
|
||||
"""Run the backup command."""
|
||||
from common.models import InvenTreeSetting
|
||||
|
||||
if InvenTreeSetting.get_setting('INVENTREE_BACKUP_ENABLE'):
|
||||
call_command("dbbackup", noinput=True, clean=True, compress=True, interactive=False)
|
||||
call_command("mediabackup", noinput=True, clean=True, compress=True, interactive=False)
|
||||
if not InvenTreeSetting.get_setting('INVENTREE_BACKUP_ENABLE', False, cache=False):
|
||||
# Backups are not enabled - exit early
|
||||
return
|
||||
|
||||
logger.info("Performing automated database backup task")
|
||||
|
||||
# Sleep a random number of seconds to prevent worker conflict
|
||||
time.sleep(random.randint(1, 5))
|
||||
|
||||
# Check for records of previous backup attempts
|
||||
last_attempt = InvenTreeSetting.get_setting('INVENTREE_BACKUP_ATTEMPT', '', cache=False)
|
||||
last_success = InvenTreeSetting.get_setting('INVENTREE_BACKUP_SUCCESS', '', cache=False)
|
||||
|
||||
try:
|
||||
backup_n_days = int(InvenTreeSetting.get_setting('INVENTREE_BACKUP_DAYS', 1, cache=False))
|
||||
except Exception:
|
||||
backup_n_days = 1
|
||||
|
||||
if last_attempt:
|
||||
try:
|
||||
last_attempt = datetime.fromisoformat(last_attempt)
|
||||
except ValueError:
|
||||
last_attempt = None
|
||||
|
||||
if last_attempt:
|
||||
# Do not attempt if the 'last attempt' at backup was within 12 hours
|
||||
threshold = timezone.now() - timezone.timedelta(hours=12)
|
||||
|
||||
if last_attempt > threshold:
|
||||
logger.info('Last backup attempt was too recent - skipping backup operation')
|
||||
return
|
||||
|
||||
# Record the timestamp of most recent backup attempt
|
||||
InvenTreeSetting.set_setting('INVENTREE_BACKUP_ATTEMPT', timezone.now().isoformat(), None)
|
||||
|
||||
if not last_attempt:
|
||||
# If there is no record of a previous attempt, exit quickly
|
||||
# This prevents the backup operation from happening when the server first launches, for example
|
||||
logger.info("No previous backup attempts recorded - waiting until tomorrow")
|
||||
return
|
||||
|
||||
if last_success:
|
||||
try:
|
||||
last_success = datetime.fromisoformat(last_success)
|
||||
except ValueError:
|
||||
last_success = None
|
||||
|
||||
# Exit early if the backup was successful within the number of required days
|
||||
if last_success:
|
||||
threshold = timezone.now() - timezone.timedelta(days=backup_n_days)
|
||||
|
||||
if last_success > threshold:
|
||||
logger.info('Last successful backup was too recent - skipping backup operation')
|
||||
return
|
||||
|
||||
call_command("dbbackup", noinput=True, clean=True, compress=True, interactive=False)
|
||||
call_command("mediabackup", noinput=True, clean=True, compress=True, interactive=False)
|
||||
|
||||
# Record the timestamp of most recent backup success
|
||||
InvenTreeSetting.set_setting('INVENTREE_BACKUP_SUCCESS', datetime.now().isoformat(), None)
|
||||
|
||||
|
||||
def send_email(subject, body, recipients, from_email=None, html_message=None):
|
||||
|
@ -969,6 +969,16 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
||||
'default': False,
|
||||
},
|
||||
|
||||
'INVENTREE_BACKUP_DAYS': {
|
||||
'name': _('Days Between Backup'),
|
||||
'description': _('Specify number of days between automated backup events'),
|
||||
'validator': [
|
||||
int,
|
||||
MinValueValidator(1),
|
||||
],
|
||||
'default': 1,
|
||||
},
|
||||
|
||||
'INVENTREE_DELETE_TASKS_DAYS': {
|
||||
'name': _('Delete Old Tasks'),
|
||||
'description': _('Background task results will be deleted after specified number of days'),
|
||||
|
@ -152,6 +152,7 @@ backup_storage: django.core.files.storage.FileSystemStorage
|
||||
background:
|
||||
workers: 4
|
||||
timeout: 90
|
||||
max_attempts: 5
|
||||
|
||||
# Optional URL schemes to allow in URL fields
|
||||
# By default, only the following schemes are allowed: ['http', 'https', 'ftp', 'ftps']
|
||||
|
@ -25,6 +25,7 @@
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_REQUIRE_CONFIRM" icon="fa-check" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_TREE_DEPTH" icon="fa-sitemap" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_BACKUP_ENABLE" icon="fa-hdd" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_BACKUP_DAYS" icon="fa-calendar-alt" %}
|
||||
<tr><td colspan='5'></td></tr>
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DELETE_TASKS_DAYS" icon="fa-calendar-alt" %}
|
||||
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DELETE_ERRORS_DAYS" icon="fa-calendar-alt" %}
|
||||
|
Loading…
Reference in New Issue
Block a user