~sirn/fanboi2

1ed63680c53ae712f70d1e81d8d4e13aade1f499 — Kridsada Thanabulpong 3 months ago 511ea39 master
chore: replace gunicorn with waitress again
5 files changed, 60 insertions(+), 58 deletions(-)

M Procfile
M fanboi2/__init__.py
M fanboi2/cmd/ctl.py
M poetry.lock
M pyproject.toml
M Procfile => Procfile +2 -2
@@ 1,4 1,4 @@
web: poetry run fbctl serve --reload --workers=1 --threads=4
web: poetry run fbctl serve --reload
worker: poetry run fbcelery worker
beat: poetry run fbcelery beat
assets: npm run gulp build watch
assets: yarn gulp build watch

M fanboi2/__init__.py => fanboi2/__init__.py +27 -2
@@ 50,6 50,24 @@ def route_name(request):


@lru_cache(maxsize=10)
def _get_asset_hash_cached(path):
    """Similar to :func:`_get_asset_hash` but the result is cached.

    :param path: An asset specification to the asset file.
    """
    if ":" in path:
        package, path = path.split(":")
        resolver = AssetResolver(package)
    else:
        resolver = AssetResolver()
    fullpath = resolver.resolve(path).abspath()
    md5 = hashlib.md5()
    with open(fullpath, "rb") as f:
        for chunk in iter(lambda: f.read(128 * md5.block_size), b""):
            md5.update(chunk)
    return md5.hexdigest()


def _get_asset_hash(path):
    """Returns an MD5 hash of the given assets path.



@@ 77,7 95,10 @@ def tagged_static_path(request, path, **kwargs):
    :param path: An asset specification to the asset file.
    :param kwargs: Arguments to pass to :meth:`request.static_path`.
    """
    kwargs["_query"] = {"h": _get_asset_hash(path)[:8]}
    if request.registry.settings["server.development"]:
        kwargs["_query"] = {"h": _get_asset_hash(path)[:8]}
    else:
        kwargs["_query"] = {"h": _get_asset_hash_cached(path)[:8]}
    return request.static_path(path, **kwargs)




@@ 165,6 186,10 @@ def make_config(settings):  # pragma: no cover
    config.include("fanboi2.views.api", route_prefix="/api")
    config.include("fanboi2.views.pages", route_prefix="/pages")
    config.include("fanboi2.views.boards", route_prefix="/")
    config.add_static_view("static", "static", cache_max_age=3600)

    if settings["server.development"]:
        config.add_static_view("static", "static")
    else:
        config.add_static_view("static", "static", cache_max_age=3600)

    return config

M fanboi2/cmd/ctl.py => fanboi2/cmd/ctl.py +10 -30
@@ 1,6 1,5 @@
import argparse
import code
import multiprocessing
import sys

from ..version import __VERSION__, __PYRAMID__


@@ 38,34 37,19 @@ def run_shell(args):

def run_serve(args):
    """Run the web server for the application."""
    from gunicorn.app.base import BaseApplication
    from waitress import serve as waitress_serve
    from ..wsgi import app as wsgi_app

    class FbserveApplication(BaseApplication):
        def __init__(self, app, options=None):
            if not options:
                options = {}
            self.options = options
            self.application = app
            super(FbserveApplication, self).__init__()
    if args.reload:
        try:
            import hupper
        except ImportError:
            sys.stderr.write("Please install dev dependencies to use reloader.\n")
            sys.exit(1)
        hupper.start_reloader("fanboi2.cmd.ctl.main")

        def load_config(self):
            for key, value in self.options.items():
                if key in self.cfg.settings and value is not None:
                    self.cfg.set(key.lower(), value)

        def load(self):
            return self.application

    options = {
        "bind": "%s:%s" % (args.host, args.port),
        "max_requests": args.max_requests,
        "reload": args.reload,
        "threads": args.threads,
        "workers": args.workers,
    }

    FbserveApplication(wsgi_app, options).run()
    waitress_serve(wsgi_app, host=args.host, port=args.port)
    sys.exit(0)


def run_gensecret(args):


@@ 84,13 68,9 @@ def main():
    shell = subparsers.add_parser("shell")
    shell.set_defaults(func=run_shell)

    cpu_count = multiprocessing.cpu_count()
    serve = subparsers.add_parser("serve")
    serve.add_argument("--port", type=int, default=6543)
    serve.add_argument("--host", default="0.0.0.0")
    serve.add_argument("--workers", type=int, default=(cpu_count * 2) + 1)
    serve.add_argument("--threads", type=int, default=1)
    serve.add_argument("--max-requests", type=int, default=1000)
    serve.add_argument("--reload", action="store_true")
    serve.set_defaults(func=run_serve)


M poetry.lock => poetry.lock +19 -22
@@ 355,23 355,6 @@ requests = ">=2.9"

[[package]]
category = "main"
description = "WSGI HTTP Server for UNIX"
name = "gunicorn"
optional = false
python-versions = ">=3.4"
version = "20.0.4"

[package.dependencies]
setuptools = ">=3.0"

[package.extras]
eventlet = ["eventlet (>=0.9.7)"]
gevent = ["gevent (>=0.13)"]
setproctitle = ["setproctitle"]
tornado = ["tornado (>=0.2)"]

[[package]]
category = "main"
description = "Python wrapper for hiredis"
name = "hiredis"
optional = false


@@ 1286,6 1269,18 @@ version = "1.3.0"

[[package]]
category = "main"
description = "Waitress WSGI server"
name = "waitress"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
version = "1.4.4"

[package.extras]
docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"]
testing = ["pytest", "pytest-cover", "coverage (>=5.0)"]

[[package]]
category = "main"
description = "WSGI request and response object"
name = "webob"
optional = false


@@ 1387,7 1382,8 @@ test = ["zope.testing"]
deploy = ["fabric", "patchwork", "invocations", "colorama"]

[metadata]
content-hash = "8606f74e079b1dbfff5a4654f08a24b47173d9dfc0fbe60dfc40688c64a08cd3"
content-hash = "b0a3e0bd0504a06db6782c00c11545336c214a09b0193eb3cb92f43ad40d4ca0"
lock-version = "1.0"
python-versions = "^3.7"

[metadata.files]


@@ 1609,10 1605,6 @@ geoip2 = [
    {file = "geoip2-2.9.0-py2.py3-none-any.whl", hash = "sha256:a37ddac2d200ffb97c736da8b8ba9d5d8dc47da6ec0f162a461b681ecac53a14"},
    {file = "geoip2-2.9.0.tar.gz", hash = "sha256:f7ffe9d258e71a42cf622ce6350d976de1d0312b9f2fbce3975c7d838b57ecf0"},
]
gunicorn = [
    {file = "gunicorn-20.0.4-py2.py3-none-any.whl", hash = "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"},
    {file = "gunicorn-20.0.4.tar.gz", hash = "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626"},
]
hiredis = [
    {file = "hiredis-1.0.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:38437a681f17c975fd22349e72c29bc643f8e7eb2d6dc5df419eac59afa4d7ce"},
    {file = "hiredis-1.0.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:102f9b9dc6ed57feb3a7c9bdf7e71cb7c278fe8df1edfcfe896bc3e0c2be9447"},


@@ 1953,6 1945,7 @@ releases = [
    {file = "repoze.lru-0.7.tar.gz", hash = "sha256:0429a75e19380e4ed50c0694e26ac8819b4ea7851ee1fc7583c8572db80aff77"},
]
requests = [
    {file = "requests-2.23.0-py2.7.egg", hash = "sha256:5d2d0ffbb515f39417009a46c14256291061ac01ba8f875b90cad137de83beb4"},
    {file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"},
    {file = "requests-2.23.0.tar.gz", hash = "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"},
]


@@ 2042,6 2035,10 @@ vine = [
    {file = "vine-1.3.0-py2.py3-none-any.whl", hash = "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"},
    {file = "vine-1.3.0.tar.gz", hash = "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87"},
]
waitress = [
    {file = "waitress-1.4.4-py2.py3-none-any.whl", hash = "sha256:3d633e78149eb83b60a07dfabb35579c29aac2d24bb803c18b26fb2ab1a584db"},
    {file = "waitress-1.4.4.tar.gz", hash = "sha256:1bb436508a7487ac6cb097ae7a7fe5413aefca610550baf58f0940e51ecfb261"},
]
webob = [
    {file = "WebOb-1.8.6-py2.py3-none-any.whl", hash = "sha256:a3c89a8e9ba0aeb17382836cdb73c516d0ecf6630ec40ec28288f3ed459ce87b"},
    {file = "WebOb-1.8.6.tar.gz", hash = "sha256:aa3a917ed752ba3e0b242234b2a373f9c4e2a75d35291dcbe977649bd21fd108"},

M pyproject.toml => pyproject.toml +2 -2
@@ 1,6 1,6 @@
[tool.poetry]
name = "fanboi2"
version = "2020.5"
version = "2020.9"
description = "Pseudonomous message board"
authors = ["Kridsada Thanabulpong <sirn@ogsite.net>"]
license = "BSD-3-Clause"


@@ 19,7 19,6 @@ argon2-cffi = "^19.1"
celery = "~4.4.1"
"dogpile.cache" = "^0.9.0"
geoip2 = "^2.9"
gunicorn = "^20.0"
hiredis = "^1.0.1"
isodate = "^0.6.0"
lark-parser = "^0.7.1"


@@ 44,6 43,7 @@ patchwork = {version = "^1.0", optional = true}
invocations = {version = "^1.4", optional = true}
colorama = {version = "^0.4.1", optional = true}
python-dotenv = "^0.12.0"
waitress = "^1.4.4"

[tool.poetry.dev-dependencies]
hupper = "^1.8"