mirror of
https://github.com/Casvt/MIND.git
synced 2026-04-03 03:00:22 -04:00
Implemented WAL journal mode for database
Some of the waitress code has been overwritten to make this work (at `backend.db.ThreadedTaskDispatcher`). The `handler_thread` function has been changed so that when the thread shuts down, the database connection for the thread is also closed (this _has_ to happen _in the thread that the connection is for/from_). The `shutdown` function opens and closes a database connection at the end, which triggers the checkpoint of the journal, writing everything to the db file and removing the `-wal` and `-shm` temporary db files.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
**/__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
@@ -129,14 +129,13 @@ dmypy.json
|
||||
.pyre/
|
||||
|
||||
# Database
|
||||
*.db
|
||||
**/*.db
|
||||
|
||||
# VS code
|
||||
*.code-workspace
|
||||
.vscode/
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
docker-compose.yml
|
||||
|
||||
@@ -146,7 +145,7 @@ docker-compose.yml
|
||||
.github/
|
||||
|
||||
# Various files
|
||||
*.md
|
||||
**/*.md
|
||||
LICENSE
|
||||
|
||||
# Tests
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM python:3.8-slim-buster
|
||||
STOPSIGNAL SIGINT
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
9
MIND.py
9
MIND.py
@@ -11,7 +11,7 @@ from flask import Flask, render_template, request
|
||||
from waitress.server import create_server
|
||||
from werkzeug.middleware.dispatcher import DispatcherMiddleware
|
||||
|
||||
from backend.db import DBConnection, close_db, setup_db
|
||||
from backend.db import DBConnection, ThreadedTaskDispatcher, close_db, setup_db
|
||||
from frontend.api import api, api_prefix, reminder_handler
|
||||
from frontend.ui import ui
|
||||
|
||||
@@ -90,7 +90,7 @@ def MIND() -> None:
|
||||
app = _create_app()
|
||||
with app.app_context():
|
||||
if isfile(_folder_path('db', 'Noted.db')):
|
||||
move(_folder_path('db', 'Noted.db'), _folder_path('db', 'MIND.db'))
|
||||
move(_folder_path('db', 'Noted.db'), _folder_path(*DB_FILENAME))
|
||||
db_location = _folder_path(*DB_FILENAME)
|
||||
makedirs(dirname(db_location), exist_ok=True)
|
||||
DBConnection.file = db_location
|
||||
@@ -98,10 +98,11 @@ def MIND() -> None:
|
||||
reminder_handler.find_next_reminder()
|
||||
|
||||
# Create waitress server and run
|
||||
server = create_server(app, host=HOST, port=PORT, threads=THREADS)
|
||||
dispatcher = ThreadedTaskDispatcher()
|
||||
dispatcher.set_thread_count(THREADS)
|
||||
server = create_server(app, _dispatcher=dispatcher, host=HOST, port=PORT, threads=THREADS)
|
||||
print(f'MIND running on http://{HOST}:{PORT}{URL_PREFIX}')
|
||||
server.run()
|
||||
print(f'\nShutting down MIND...')
|
||||
|
||||
# Stopping thread
|
||||
reminder_handler.stop_handling()
|
||||
|
||||
@@ -7,8 +7,11 @@ from time import time
|
||||
from typing import Union
|
||||
|
||||
from flask import g
|
||||
from waitress.task import ThreadedTaskDispatcher as OldThreadedTaskDispatcher
|
||||
|
||||
__DATABASE_VERSION__ = 5
|
||||
from backend.custom_exceptions import AccessUnauthorized, UserNotFound
|
||||
|
||||
__DATABASE_VERSION__ = 6
|
||||
|
||||
class Singleton(type):
|
||||
_instances = {}
|
||||
@@ -20,6 +23,18 @@ class Singleton(type):
|
||||
|
||||
return cls._instances[i]
|
||||
|
||||
class ThreadedTaskDispatcher(OldThreadedTaskDispatcher):
|
||||
def handler_thread(self, thread_no: int) -> None:
|
||||
super().handler_thread(thread_no)
|
||||
i = f'{DBConnection}{current_thread()}'
|
||||
if i in Singleton._instances and not Singleton._instances[i].closed:
|
||||
Singleton._instances[i].close()
|
||||
|
||||
def shutdown(self, cancel_pending: bool = True, timeout: int = 5) -> bool:
|
||||
print('Shutting down MIND...')
|
||||
super().shutdown(cancel_pending, timeout)
|
||||
DBConnection(20.0).close()
|
||||
|
||||
class DBConnection(Connection, metaclass=Singleton):
|
||||
file = ''
|
||||
|
||||
@@ -177,13 +192,22 @@ def migrate_db(current_db_version: int) -> None:
|
||||
COMMIT;
|
||||
""")
|
||||
current_db_version = 5
|
||||
|
||||
|
||||
if current_db_version == 5:
|
||||
# V5 -> V6
|
||||
from backend.users import User
|
||||
try:
|
||||
User('User1', 'Password1').delete()
|
||||
except (UserNotFound, AccessUnauthorized):
|
||||
pass
|
||||
|
||||
return
|
||||
|
||||
def setup_db() -> None:
|
||||
"""Setup the database
|
||||
"""
|
||||
cursor = get_db()
|
||||
cursor.execute("PRAGMA journal_mode = wal;")
|
||||
|
||||
cursor.executescript("""
|
||||
CREATE TABLE IF NOT EXISTS users(
|
||||
|
||||
Reference in New Issue
Block a user