Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/mongo_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,6 @@ class Logs(MongoModel):
filename = fields.CharField()
funcName = fields.CharField()
lineno = fields.IntegerField()

class StorageMeta(MongoModel):
used_size = fields.IntegerField()
43 changes: 40 additions & 3 deletions app/mongo_odm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from gridfs import GridFSBucket, NoFile
from pymodm import connect
from pymodm.connection import _get_db
from pymodm.errors import ValidationError
from pymodm.errors import ValidationError, DoesNotExist
from pymodm.files import GridFSStorage
from pymongo import ReturnDocument
from pymongo.errors import CollectionInvalid
Expand All @@ -23,7 +23,7 @@
RecognizedAudioToProcess,
RecognizedPresentationsToProcess, Sessions,
TaskAttempts, TaskAttemptsToPassBack, Tasks,
Trainings, TrainingsToProcess)
Trainings, TrainingsToProcess, StorageMeta)
from app.status import (AudioStatus, PassBackStatus, PresentationStatus,
TrainingStatus)
from app.utils import remove_blank_and_none
Expand All @@ -42,7 +42,17 @@ def __new__(cls):
return cls.instance

def add_file(self, file, filename=uuid.uuid4()):
return self.storage.save(name=filename, content=file)
try:
file.seek(0, os.SEEK_END)
size = file.tell()
file.seek(0)
except:
if(isinstance(file, str)):
size = len(file)
self.check_storage_limit(size)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в случае, если БД переполнена - загрузка (и тренировка) должна быть прервана - иначе сейчас просто пишется сообщение в лог и логика идет дальше

_id = self.storage.save(name=filename, content=file)
self.update_storage_size(size)
return _id

def read_and_add_file(self, path, filename=None):
if filename is None:
Expand All @@ -67,6 +77,33 @@ def get_file(self, file_id):
except (NoFile, ValidationError, InvalidId) as e:
logger.warning('file_id = {}, {}.'.format(file_id, e))
return None

def _get_or_create_storage_meta(self):
try:
return StorageMeta.objects.get({})
except DoesNotExist:
meta = StorageMeta(used_size=0).save()
return meta

def get_used_storage_size(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

добавьте метод для актуализации данных (вдруг где-то логика дала сбой и насчитала нам что-то, или вручную из бд были удалены файлы) - ему нужно будет пройтись по всем документам и посчитать их общий вес

  • на странице capacity сделайте кнопку для такого обновления данных, чтобы по запросу пересчитывать размер и выводить актуальный

return self._get_or_create_storage_meta().used_size

def set_used_storage_size(self, size):
meta = self._get_or_create_storage_meta()
meta.used_size = size
meta.save()

def update_storage_size(self, deltasize):
meta = self._get_or_create_storage_meta()
meta.used_size += deltasize
meta.save()

def check_storage_limit(self, new_file_size):
max_size = int(Config.c.constants.storage_max_size_mbytes)*1024*1024
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поскольку вы вынесли логику в DBManager - давайте лимит запишем в его поле (тогда не нужно будет каждый раз преобразовывать данные из конфига)

current_size = self.get_used_storage_size()
if current_size + new_file_size > max_size:
logger.warning('current_size = {}, new file size = {}'.format(current_size, new_file_size))



class TrainingsDBManager:
Expand Down
25 changes: 25 additions & 0 deletions app/routes/capacity.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Добавьте ссылку на эту страницу в /admin

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from flask import Blueprint, render_template
from app.mongo_odm import DBManager
from app.config import Config
from app.root_logger import get_root_logger
from app.lti_session_passback.auth_checkers import is_admin

logger = get_root_logger()

routes_capacity = Blueprint(
'routes_capacity', __name__, url_prefix='/capacity')

@routes_capacity.route('/', methods=['GET'])
def storage_capacity():
if not is_admin():
return {}, 404
current_size = DBManager().get_used_storage_size()
max_size = int(Config.c.constants.storage_max_size_mbytes)*1024*1024
ratio = current_size / max_size
return render_template(
'capacity.html',
size=round(current_size / 1, 2),
max_size=round(max_size / 1, 2),
ratio=round(ratio * 100, 1)
)

19 changes: 19 additions & 0 deletions app/templates/capacity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends 'base.html' %}

{% block content %}
<div class="container mt-4">
<div class="card">
<div class="card-body">
<h4 class="card-title">Загруженность Базы Данных</h4>
<p><strong>Использовано:</strong> {{ size }} байт</p>
<p><strong>Максимум:</strong> {{ max_size }} байт</p>
<p><strong>Заполнено:</strong> {{ ratio }}%</p>
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: {{ ratio }}%;" aria-valuenow="{{ ratio }}" aria-valuemin="0" aria-valuemax="100">
{{ ratio }}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
2 changes: 2 additions & 0 deletions app/web_speech_trainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from app.routes.presentations import routes_presentations
from app.routes.trainings import routes_trainings
from app.routes.version import routes_version
from app.routes.capacity import routes_capacity
from app.status import PassBackStatus, TrainingStatus
from app.training_manager import TrainingManager
from app.utils import ALLOWED_EXTENSIONS, DEFAULT_EXTENSION
Expand All @@ -53,6 +54,7 @@
app.register_blueprint(routes_presentations)
app.register_blueprint(routes_trainings)
app.register_blueprint(routes_version)
app.register_blueprint(routes_capacity)

logger = get_root_logger(service_name='web')

Expand Down
1 change: 1 addition & 0 deletions app_conf/config.ini
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

кажется, в тестовом конфиге это тоже пригодится - как минимум, для selenium-теста, проверяющего страницу capacity

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ lti_consumer_key=secretconsumerkey
lti_consumer_secret=supersecretconsumersecret
version_file=VERSION.json
backup_path=../dump/database-dump/
storage_max_size_mbytes=20000

[mongodb]
url=mongodb://db:27017/
Expand Down