-
Notifications
You must be signed in to change notification settings - Fork 1
352 DB limitation #427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
352 DB limitation #427
Changes from 2 commits
9a5e998
3a58841
927930f
8a20911
8802224
1d4e949
dcdab5b
fdf1bef
489a3fd
f7011df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -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 | ||
|
|
@@ -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) | ||
| _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: | ||
|
|
@@ -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): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. добавьте метод для актуализации данных (вдруг где-то логика дала сбой и насчитала нам что-то, или вручную из бд были удалены файлы) - ему нужно будет пройтись по всем документам и посчитать их общий вес
|
||
| 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 | ||
|
||
| 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: | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
| ) | ||
|
|
| 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 %} |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. кажется, в тестовом конфиге это тоже пригодится - как минимум, для selenium-теста, проверяющего страницу capacity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
в случае, если БД переполнена - загрузка (и тренировка) должна быть прервана - иначе сейчас просто пишется сообщение в лог и логика идет дальше