Improved scheduling using APScheduler
This commit is contained in:
parent
df7b031024
commit
bdb4933887
4 changed files with 128 additions and 21 deletions
|
@ -1,38 +1,51 @@
|
||||||
import logging
|
import logging
|
||||||
import threading
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from threading import Lock
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
from webdav3.client import Client, Resource
|
from webdav3.client import Client, Resource
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DavFile:
|
class DavFile:
|
||||||
|
__instances = None
|
||||||
|
|
||||||
def __init__(self, client: Client, path: Any) -> None:
|
def __init__(self, client: Client, path: Any) -> None:
|
||||||
self.__resource: Resource = client.resource(path)
|
self.__resource: Resource = client.resource(path)
|
||||||
self.__buffer = BytesIO()
|
self.__buffer = BytesIO()
|
||||||
self.__lock = threading.Lock()
|
self.__lock = Lock()
|
||||||
|
|
||||||
|
# register
|
||||||
|
if DavFile.__instances is None:
|
||||||
|
DavFile.__instances = []
|
||||||
|
|
||||||
|
DavFile.__instances.append(self)
|
||||||
|
|
||||||
def update(self) -> None:
|
def update(self) -> None:
|
||||||
_logger.debug(f"updating {self.__resource}")
|
_logger.info(f"updating {self.__resource}")
|
||||||
with self.__lock:
|
with self.__lock:
|
||||||
self.__buffer.seek(0)
|
self.__buffer.seek(0)
|
||||||
self.__buffer.truncate(0)
|
self.__buffer.truncate(0)
|
||||||
self.__resource.write_to(self.__buffer)
|
self.__resource.write_to(self.__buffer)
|
||||||
|
|
||||||
def refresh(self, refresh_interval: int = 5) -> threading.Event:
|
@classmethod
|
||||||
stop_handle = threading.Event()
|
def refresh(cls, refresh_interval: int = 5) -> AsyncIOScheduler:
|
||||||
|
scheduler = AsyncIOScheduler()
|
||||||
|
|
||||||
def refresh_loop() -> None:
|
def tick() -> None:
|
||||||
while not stop_handle.wait(refresh_interval):
|
for davfile in DavFile.__instances:
|
||||||
self.update()
|
davfile.update()
|
||||||
|
|
||||||
thread = threading.Thread(target=refresh_loop)
|
scheduler.add_job(tick)
|
||||||
thread.daemon = True
|
scheduler.add_job(
|
||||||
thread.start()
|
tick, "interval",
|
||||||
|
seconds=refresh_interval,
|
||||||
|
)
|
||||||
|
scheduler.start()
|
||||||
|
|
||||||
return stop_handle
|
return scheduler
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bytes(self) -> bytes:
|
def bytes(self) -> bytes:
|
||||||
|
|
|
@ -3,7 +3,8 @@ import logging
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from markdown import Markdown
|
from markdown import Markdown
|
||||||
|
|
||||||
from .. import CLIENT, SETTINGS
|
from .. import CLIENT
|
||||||
|
from ..config import SETTINGS
|
||||||
from ..dav_file import DavFile
|
from ..dav_file import DavFile
|
||||||
|
|
||||||
router = APIRouter(prefix="/text", tags=["text"])
|
router = APIRouter(prefix="/text", tags=["text"])
|
||||||
|
@ -11,18 +12,21 @@ router = APIRouter(prefix="/text", tags=["text"])
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
_md = Markdown()
|
_md = Markdown()
|
||||||
|
|
||||||
_message = DavFile(client=CLIENT, path="message.txt")
|
_message = ""
|
||||||
_ticker = DavFile(client=CLIENT, path="ticker.txt")
|
_ticker = ""
|
||||||
_title = DavFile(client=CLIENT, path="title.txt")
|
_title = ""
|
||||||
|
|
||||||
|
|
||||||
@router.on_event("startup")
|
@router.on_event("startup")
|
||||||
async def on_startup():
|
async def on_startup():
|
||||||
_logger.debug("text router startup")
|
global _message, _ticker, _title
|
||||||
|
|
||||||
_message.refresh()
|
_message = DavFile(client=CLIENT, path="message.txt")
|
||||||
_ticker.refresh()
|
_ticker = DavFile(client=CLIENT, path="ticker.txt")
|
||||||
_title.refresh()
|
_title = DavFile(client=CLIENT, path="title.txt")
|
||||||
|
DavFile.refresh(60)
|
||||||
|
|
||||||
|
_logger.debug("text router started")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/message")
|
@router.get("/message")
|
||||||
|
|
91
api/poetry.lock
generated
91
api/poetry.lock
generated
|
@ -15,6 +15,32 @@ doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||||
test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"]
|
test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"]
|
||||||
trio = ["trio (>=0.16)"]
|
trio = ["trio (>=0.16)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "apscheduler"
|
||||||
|
version = "3.9.1"
|
||||||
|
description = "In-process task scheduler with Cron-like capabilities"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pytz = "*"
|
||||||
|
six = ">=1.4.0"
|
||||||
|
tzlocal = ">=2.0,<3.0.0 || >=4.0.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
asyncio = ["trollius"]
|
||||||
|
doc = ["sphinx", "sphinx-rtd-theme"]
|
||||||
|
gevent = ["gevent"]
|
||||||
|
mongodb = ["pymongo (>=3.0)"]
|
||||||
|
redis = ["redis (>=3.0)"]
|
||||||
|
rethinkdb = ["rethinkdb (>=2.4.0)"]
|
||||||
|
sqlalchemy = ["sqlalchemy (>=0.8)"]
|
||||||
|
testing = ["mock", "pytest", "pytest-asyncio", "pytest-asyncio (<0.6)", "pytest-cov", "pytest-tornado5"]
|
||||||
|
tornado = ["tornado (>=4.3)"]
|
||||||
|
twisted = ["twisted"]
|
||||||
|
zookeeper = ["kazoo"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
version = "2022.6.15"
|
version = "2022.6.15"
|
||||||
|
@ -169,6 +195,25 @@ python-versions = ">=3.5"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cli = ["click (>=5.0)"]
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytz"
|
||||||
|
version = "2022.2.1"
|
||||||
|
description = "World timezone definitions, modern and historical"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytz-deprecation-shim"
|
||||||
|
version = "0.1.0.post0"
|
||||||
|
description = "Shims to make deprecation of pytz easier"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
tzdata = {version = "*", markers = "python_version >= \"3.6\""}
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.28.1"
|
version = "2.28.1"
|
||||||
|
@ -226,6 +271,30 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tzdata"
|
||||||
|
version = "2022.2"
|
||||||
|
description = "Provider of IANA time zone data"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tzlocal"
|
||||||
|
version = "4.2"
|
||||||
|
description = "tzinfo object for the local timezone"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pytz-deprecation-shim = "*"
|
||||||
|
tzdata = {version = "*", markers = "platform_system == \"Windows\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"]
|
||||||
|
test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "1.26.12"
|
version = "1.26.12"
|
||||||
|
@ -282,13 +351,17 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "a8edb56f5824246d8a490c280bf11318d1efa11d6109b4982b8adf15b391d587"
|
content-hash = "136b9208bffca16de395a3444ca9d172d7e6d7e40866eea987174fa7b69822c7"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
anyio = [
|
anyio = [
|
||||||
{file = "anyio-3.6.1-py3-none-any.whl", hash = "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"},
|
{file = "anyio-3.6.1-py3-none-any.whl", hash = "sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be"},
|
||||||
{file = "anyio-3.6.1.tar.gz", hash = "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b"},
|
{file = "anyio-3.6.1.tar.gz", hash = "sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b"},
|
||||||
]
|
]
|
||||||
|
apscheduler = [
|
||||||
|
{file = "APScheduler-3.9.1-py2.py3-none-any.whl", hash = "sha256:ddc25a0ddd899de44d7f451f4375fb971887e65af51e41e5dcf681f59b8b2c9a"},
|
||||||
|
{file = "APScheduler-3.9.1.tar.gz", hash = "sha256:65e6574b6395498d371d045f2a8a7e4f7d50c6ad21ef7313d15b1c7cf20df1e3"},
|
||||||
|
]
|
||||||
certifi = [
|
certifi = [
|
||||||
{file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
|
{file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
|
||||||
{file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
|
{file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
|
||||||
|
@ -442,6 +515,14 @@ python-dotenv = [
|
||||||
{file = "python-dotenv-0.20.0.tar.gz", hash = "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f"},
|
{file = "python-dotenv-0.20.0.tar.gz", hash = "sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f"},
|
||||||
{file = "python_dotenv-0.20.0-py3-none-any.whl", hash = "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938"},
|
{file = "python_dotenv-0.20.0-py3-none-any.whl", hash = "sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938"},
|
||||||
]
|
]
|
||||||
|
pytz = [
|
||||||
|
{file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
|
||||||
|
{file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
|
||||||
|
]
|
||||||
|
pytz-deprecation-shim = [
|
||||||
|
{file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"},
|
||||||
|
{file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"},
|
||||||
|
]
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
|
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
|
||||||
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
|
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
|
||||||
|
@ -462,6 +543,14 @@ typing-extensions = [
|
||||||
{file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
|
{file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
|
||||||
{file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
|
{file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
|
||||||
]
|
]
|
||||||
|
tzdata = [
|
||||||
|
{file = "tzdata-2022.2-py2.py3-none-any.whl", hash = "sha256:c3119520447d68ef3eb8187a55a4f44fa455f30eb1b4238fa5691ba094f2b05b"},
|
||||||
|
{file = "tzdata-2022.2.tar.gz", hash = "sha256:21f4f0d7241572efa7f7a4fdabb052e61b55dc48274e6842697ccdf5253e5451"},
|
||||||
|
]
|
||||||
|
tzlocal = [
|
||||||
|
{file = "tzlocal-4.2-py3-none-any.whl", hash = "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745"},
|
||||||
|
{file = "tzlocal-4.2.tar.gz", hash = "sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"},
|
||||||
|
]
|
||||||
urllib3 = [
|
urllib3 = [
|
||||||
{file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"},
|
{file = "urllib3-1.26.12-py2.py3-none-any.whl", hash = "sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997"},
|
||||||
{file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"},
|
{file = "urllib3-1.26.12.tar.gz", hash = "sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e"},
|
||||||
|
|
|
@ -11,6 +11,7 @@ python = "^3.9"
|
||||||
uvicorn = "^0.18.3"
|
uvicorn = "^0.18.3"
|
||||||
webdavclient3 = "3.14.5"
|
webdavclient3 = "3.14.5"
|
||||||
Markdown = "^3.4.1"
|
Markdown = "^3.4.1"
|
||||||
|
APScheduler = "^3.9.1"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
# pytest = "^5.2"
|
# pytest = "^5.2"
|
||||||
|
|
Loading…
Reference in a new issue