fixing slowness when screen_pub queries the db #4

Merged
ben merged 7 commits from fix-db-read into main 2022-09-18 14:17:00 +00:00
6 changed files with 57 additions and 46 deletions

View File

@ -19,12 +19,13 @@ RUN apt-get update && \
chown -R -v ${USER_NAME}. /opt/${REPO_NAME} chown -R -v ${USER_NAME}. /opt/${REPO_NAME}
USER ${USER_NAME} USER ${USER_NAME}
WORKDIR /opt/${REPO_NAME} WORKDIR /home/${USER_NAME}
ENV PATH="/home/${USER_NAME}/.local/bin:${PATH}" ENV PATH="/home/${USER_NAME}/.local/bin:${PATH}"
FROM base as builder FROM base as builder
ARG PIP_REPO_URL="https://git.sudo.is/api/packages/ben/pypi" ARG PIP_REPO_URL="https://git.sudo.is/api/packages/ben/pypi"
ARG PIP_REPO_NAME="gitea" ARG PIP_REPO_NAME="gitea"
WORKDIR /opt/${REPO_NAME}
# --pre: enable installing pre-releases and dev-releases # --pre: enable installing pre-releases and dev-releases
RUN python3 -m pip install poetry --pre && \ RUN python3 -m pip install poetry --pre && \
@ -74,4 +75,5 @@ RUN ls -1 /opt/${REPO_NAME}/dist && \
HEALTHCHECK --start-period=5s --interval=15s --timeout=1s \ HEALTHCHECK --start-period=5s --interval=15s --timeout=1s \
CMD ruok_${REPO_NAME} CMD ruok_${REPO_NAME}
ENTRYPOINT ['sudoisbot'] ENTRYPOINT ["sudoisbot"]
CMD []

24
poetry.lock generated
View File

@ -325,7 +325,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-
[[package]] [[package]]
name = "keyring" name = "keyring"
version = "23.9.1" version = "23.9.3"
description = "Store and access your passwords safely." description = "Store and access your passwords safely."
category = "dev" category = "dev"
optional = false optional = false
@ -580,6 +580,18 @@ category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "pymysql"
version = "1.0.2"
description = "Pure Python MySQL Driver"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
rsa = ["cryptography"]
ed25519 = ["PyNaCl (>=1.4.0)"]
[[package]] [[package]]
name = "pyparsing" name = "pyparsing"
version = "3.0.9" version = "3.0.9"
@ -923,7 +935,7 @@ telegram = ["python-telegram-bot"]
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "fc8b29b88ed8498ad730df20f70aaee6f5dd6835930a434b48f90b23a11b7c3b" content-hash = "91854d75e5de47e9f5218c09b2037aef57cef4550c1dae087f3e77b0e3b6ae74"
[metadata.files] [metadata.files]
apscheduler = [ apscheduler = [
@ -1142,8 +1154,8 @@ jsonschema = [
{file = "jsonschema-4.16.0.tar.gz", hash = "sha256:165059f076eff6971bae5b742fc029a7b4ef3f9bcf04c14e4776a7605de14b23"}, {file = "jsonschema-4.16.0.tar.gz", hash = "sha256:165059f076eff6971bae5b742fc029a7b4ef3f9bcf04c14e4776a7605de14b23"},
] ]
keyring = [ keyring = [
{file = "keyring-23.9.1-py3-none-any.whl", hash = "sha256:3565b9e4ea004c96e158d2d332a49f466733d565bb24157a60fd2e49f41a0fd1"}, {file = "keyring-23.9.3-py3-none-any.whl", hash = "sha256:69732a15cb1433bdfbc3b980a8a36a04878a6cfd7cb99f497b573f31618001c0"},
{file = "keyring-23.9.1.tar.gz", hash = "sha256:39e4f6572238d2615a82fcaa485e608b84b503cf080dc924c43bbbacb11c1c18"}, {file = "keyring-23.9.3.tar.gz", hash = "sha256:69b01dd83c42f590250fe7a1f503fc229b14de83857314b1933a3ddbf595c4a5"},
] ]
loguru = [ loguru = [
{file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"}, {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
@ -1282,6 +1294,10 @@ pylev = [
{file = "pylev-1.4.0-py2.py3-none-any.whl", hash = "sha256:7b2e2aa7b00e05bb3f7650eb506fc89f474f70493271a35c242d9a92188ad3dd"}, {file = "pylev-1.4.0-py2.py3-none-any.whl", hash = "sha256:7b2e2aa7b00e05bb3f7650eb506fc89f474f70493271a35c242d9a92188ad3dd"},
{file = "pylev-1.4.0.tar.gz", hash = "sha256:9e77e941042ad3a4cc305dcdf2b2dec1aec2fbe3dd9015d2698ad02b173006d1"}, {file = "pylev-1.4.0.tar.gz", hash = "sha256:9e77e941042ad3a4cc305dcdf2b2dec1aec2fbe3dd9015d2698ad02b173006d1"},
] ]
pymysql = [
{file = "PyMySQL-1.0.2-py3-none-any.whl", hash = "sha256:41fc3a0c5013d5f039639442321185532e3e2c8924687abe6537de157d403641"},
{file = "PyMySQL-1.0.2.tar.gz", hash = "sha256:816927a350f38d56072aeca5dfb10221fe1dc653745853d30a216637f5d7ad36"},
]
pyparsing = [ pyparsing = [
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},

View File

@ -14,10 +14,11 @@ loguru = "^0.6.0"
PyYAML = "^6.0" PyYAML = "^6.0"
pyzmq = "^23.2.1" pyzmq = "^23.2.1"
sudoistemper = "^0.1.0" sudoistemper = "^0.1.0"
peewee = "^3.15.1" peewee = "^3.15.2"
requests = "^2.28.1" requests = "^2.28.1"
python-dateutil = "^2.8.2" python-dateutil = "^2.8.2"
python-telegram-bot = { version = "^13.1", optional = true } python-telegram-bot = { version = "^13.1", optional = true }
PyMySQL = "^1.0.2"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
autopep8 = "^1.7.0" autopep8 = "^1.7.0"

View File

@ -2,6 +2,6 @@
set -e set -e
source ./docker/docker.env source ./scripts/docker.env
docker run --rm -it ${repo_name}:${docker_tag} $* docker run --rm -it ${repo_name}:${docker_tag} $*

View File

@ -2,13 +2,10 @@
# ansible for now # ansible for now
import argparse from datetime import datetime, timezone
from datetime import datetime, timezone, timedelta
from os import path
import sys
import random import random
import time import time
from dataclasses import dataclass, field, asdict from dataclasses import dataclass, field
from itertools import islice from itertools import islice
from loguru import logger from loguru import logger
@ -16,15 +13,18 @@ from loguru import logger
from sudoisbot.network.pub import Publisher from sudoisbot.network.pub import Publisher
from sudoisbot.sink.models import Temperatures, People, Weather, dbconnect from sudoisbot.sink.models import Temperatures, People, Weather, dbconnect
def chunk(it, size=10): def chunk(it, size=10):
it = iter(it) it = iter(it)
return list(iter(lambda: list(islice(it, size)), [])) return list(iter(lambda: list(islice(it, size)), []))
def bark(): def bark():
numberofwoofs = random.randint(1, 3) numberofwoofs = random.randint(1, 3)
woofs = " " + ", ".join(["woof"] * numberofwoofs) woofs = " " + ", ".join(["woof"] * numberofwoofs)
return woofs return woofs
@dataclass @dataclass
class ScreenPublisher(Publisher): class ScreenPublisher(Publisher):
addr: str addr: str
@ -37,7 +37,6 @@ class ScreenPublisher(Publisher):
statedir: str = "/dev/shm" statedir: str = "/dev/shm"
msgs: list = field(default_factory=list) msgs: list = field(default_factory=list)
no_loop: bool = False no_loop: bool = False
dry_run: bool = False dry_run: bool = False
@ -83,35 +82,31 @@ class ScreenPublisher(Publisher):
return " ".join(homebodies) return " ".join(homebodies)
except ValueError as e: except ValueError as e:
logger.error(e)
return "- - -" return "- - -"
def make_text(self): def make_text(self):
return random.choice(self.msgs + [self.align_center(bark())]) return random.choice(self.msgs + [self.align_center(bark())])
def make_temps(self): def make_temps(self):
l = list() temps = list()
for a in ['bedroom', 'study', 'livingroom', 'ls54', 'outdoor']: for a in ['bedroom', 'study', 'livingroom', 'ls54', 'outdoor']:
# .replace does not mutate original string # .replace does not mutate original string
shortname = a.replace('room', 'r') shortname = a.replace('room', 'r')
try: try:
t0 = time.time()
result = Temperatures.get_last(a) result = Temperatures.get_last(a)
t1 = time.time()
print(f"query for: {t1-t0}s, name='{a}'")
tempstr = f"{result.temp:.1f}" tempstr = f"{result.temp:.1f}"
if result.temp < 10.0: if result.temp < 10.0:
tempstr = " " + tempstr tempstr = " " + tempstr
l.append(f"{shortname}: {tempstr} C") temps.append(f"{shortname}: {tempstr} C")
except KeyError: except KeyError:
logger.trace(f"no recent temp for '{a}'") logger.trace(f"no recent temp for '{a}'")
l.append(f"{shortname}: -- C") temps.append(f"{shortname}: -- C")
fill = max([len(a) for a in temps])
fill = max([len(a) for a in l]) chunks = chunk([a.rjust(fill) for a in temps], 2)
chunks = chunk([a.rjust(fill) for a in l], 2)
temp_rows = list() temp_rows = list()
for row in chunks: for row in chunks:
@ -122,7 +117,7 @@ class ScreenPublisher(Publisher):
return "\n".join(temp_rows) return "\n".join(temp_rows)
def publish(self): def publish(self):
woof = " " + bark() woof = " " + bark() # noqa
weth = self.make_weather() weth = self.make_weather()
temps = self.make_temps() temps = self.make_temps()
@ -132,7 +127,6 @@ class ScreenPublisher(Publisher):
rain = self.make_rain(weth) rain = self.make_rain(weth)
text = f"{temps}\n{weth}\n{text}" text = f"{temps}\n{weth}\n{text}"
# add back logic to turn update intervals down pr stop when # add back logic to turn update intervals down pr stop when
# nodody is home # nodody is home
if len(folk) > 0: if len(folk) > 0:
@ -165,15 +159,14 @@ class ScreenPublisher(Publisher):
if self.no_loop: if self.no_loop:
raise StopIteration raise StopIteration
def main(args, config): def main(args, config):
dbconnect(**config['mysql'])
db = dbconnect(**config['mysql'])
addr = config['addr'] addr = config['addr']
# people_home = config['people_home'] # people_home = config['people_home']
kwargs = {**config['screen'], kwargs = {
**config['screen'],
**{ **{
'rotation': args.rotation, 'rotation': args.rotation,
'people': config['people'], 'people': config['people'],
@ -181,7 +174,6 @@ def main(args, config):
'dry_run': args.dry_run, 'dry_run': args.dry_run,
'no_loop': args.no_loop 'no_loop': args.no_loop
}} }}
with ScreenPublisher(addr=addr, **kwargs) as p: with ScreenPublisher(addr=addr, **kwargs) as p:
p.loop() p.loop()

View File

@ -22,9 +22,9 @@ def dbconnect(**mysqlconf):
class BaseModel(peewee.Model): class BaseModel(peewee.Model):
@classmethod @classmethod
def get_last(cls, name): def get_last(cls, name):
# http://docs.peewee-orm.com/en/latest/peewee/querying.html
return cls.select().where( return cls.select().where(
cls.name == name).order_by( cls.name == name).order_by(-cls.id).get()
cls.time.desc()).get()
@classmethod @classmethod
def get_last_many(cls, names): def get_last_many(cls, names):