Compare commits

...

2 commits

5 changed files with 70 additions and 40 deletions

View file

@ -6,12 +6,12 @@ py_project(
main_deps = [
"//projects/anosql",
"//projects/anosql-migrations",
"//projects/cherry-shim",
py_requirement("attrs"),
py_requirement("click"),
py_requirement("flask"),
py_requirement("jinja2"),
py_requirement("octorest"),
py_requirement("cherrypy"),
],
lib_data = [
"//projects/tentacles/src/python/tentacles/static/css",

View file

@ -3,13 +3,13 @@
"""The core app entrypoint."""
from datetime import datetime
import logging
from pathlib import Path
import tomllib
import cherrypy
import click
from flask import Flask, request
from cherry_shim import shim
from tentacles.blueprints import (
api,
file_ui,
@ -19,7 +19,7 @@ from tentacles.blueprints import (
)
from tentacles.globals import _ctx, Ctx, ctx
from tentacles.store import Store
from tentacles.workers import create_workers
from tentacles.workers import Worker
@click.group()
@ -27,7 +27,7 @@ def cli():
pass
def store_factory(app):
def db_factory(app):
store = Store(app.config.get("db", {}).get("uri"))
store.connect()
return store
@ -35,7 +35,7 @@ def store_factory(app):
def custom_ctx(app, wsgi_app):
def helper(environ, start_response):
store = store_factory(app)
store = db_factory(app)
token = _ctx.set(Ctx(store))
try:
return wsgi_app(environ, start_response)
@ -76,21 +76,11 @@ def user_session():
ctx.is_admin = user.group_id == 0
@cli.command()
@click.option("--hostname", "hostname", type=str, default="0.0.0.0")
@click.option("--port", "port", type=int, default=8080)
@click.option("--config", type=Path)
def serve(hostname: str, port: int, config: Path):
def make_app():
app = Flask(__name__)
if config:
with open(config, "rb") as fp:
app.config.update(tomllib.load(fp))
print(app.config)
# Before first request
create_j2_request_global(app)
shutdown_event = create_workers(app, store_factory)
# Before request
app.before_request(user_session)
@ -104,13 +94,51 @@ def serve(hostname: str, port: int, config: Path):
# Shove our middleware in there
app.wsgi_app = custom_ctx(app, app.wsgi_app)
cherry = shim(app)
# And run the blame thing
try:
cherry.run(host=hostname, port=port)
finally:
shutdown_event.set()
return app
@cli.command()
@click.option("--hostname", "hostname", type=str, default="0.0.0.0")
@click.option("--port", "port", type=int, default=8080)
@click.option("--config", type=Path)
def serve(hostname: str, port: int, config: Path):
logging.basicConfig(
format="%(asctime)s %(relativeCreated)6d %(threadName)s - %(name)s - %(levelname)s - %(message)s",
level=logging.INFO,
)
logging.getLogger("tentacles").setLevel(logging.DEBUG)
app = make_app()
if config:
with open(config, "rb") as fp:
app.config.update(tomllib.load(fp))
print(app.config)
cherrypy.server.unsubscribe()
server = cherrypy._cpserver.Server()
cherrypy.config.update(
{
"environment": "production",
"engine.autoreload.on": False,
}
)
cherrypy.tree.graft(app, "/")
server.socket_host = hostname
server.socket_port = port
server.thread_pool = 16
server.shutdown_timeout = 1
server.subscribe()
# Spawn the worker thread
Worker(cherrypy.engine, app, db_factory, frequency=5).start()
# Run the server
cherrypy.engine.start()
cherrypy.engine.block()
if __name__ == "__main__":

View file

@ -11,13 +11,13 @@ from contextlib import closing
from datetime import datetime, timedelta
import logging
from pathlib import Path
from threading import Event, Thread
from threading import Event
from time import sleep
from typing import Callable
from urllib import parse as urlparse
from cherrypy.process.plugins import Monitor
from fastmail import FastMailSMTP
from flask import Flask as App, render_template
from flask import Flask as App
from octorest import OctoRest as _OR
from requests import Response
from requests.exceptions import (
@ -271,18 +271,18 @@ def send_emails(app, store: Store):
store.send_email(message.id)
@corn_job(timedelta(seconds=5))
def run_worker(app: App, db_factory):
with app.app_context(), closing(db_factory(app)) as store:
poll_printers(app, store)
assign_jobs(app, store)
push_jobs(app, store)
revoke_jobs(app, store)
pull_jobs(app, store)
send_emails(app, store)
class Worker(Monitor):
def __init__(self, bus, app, db_factory, **kwargs):
self._app = app
self._db_factory = db_factory
super().__init__(bus, self.callback, **kwargs)
def create_workers(app, db_factory: Callable[[App], Store]) -> Event:
Thread(target=run_worker, args=[app, db_factory]).start()
return SHUTDOWN
def callback(self):
log.debug("Tick")
with self._app.app_context(), closing(self._db_factory(self._app)) as store:
poll_printers(self._app, store)
assign_jobs(self._app, store)
push_jobs(self._app, store)
revoke_jobs(self._app, store)
pull_jobs(self._app, store)
send_emails(self._app, store)

View file

@ -1,5 +1,6 @@
-c constraints.in
aiosql
ExifRead
aiohttp
aiohttp_basicauth

View file

@ -1,6 +1,7 @@
aiohttp==3.8.4
aiohttp-basicauth==1.0.0
aiosignal==1.3.1
aiosql==8.0
alabaster==0.7.13
async-lru==2.0.2
async-timeout==4.0.2