Enable pc prod without redis (#85)
* Make app callable * Enable pc prod without redis * Add missing code
This commit is contained in:
parent
23fc3cadd9
commit
d39bcc7d38
@ -74,6 +74,14 @@ class App(Base):
|
|||||||
"""
|
"""
|
||||||
return f"<App state={self.state.__name__}>"
|
return f"<App state={self.state.__name__}>"
|
||||||
|
|
||||||
|
def __call__(self) -> fastapi.FastAPI:
|
||||||
|
"""Run the backend api instance.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The backend api.
|
||||||
|
"""
|
||||||
|
return self.api
|
||||||
|
|
||||||
def add_default_endpoints(self):
|
def add_default_endpoints(self):
|
||||||
"""Add the default endpoints."""
|
"""Add the default endpoints."""
|
||||||
# To test the server.
|
# To test the server.
|
||||||
|
@ -56,12 +56,10 @@ BUN_PATH = "$HOME/.bun/bin/bun"
|
|||||||
INSTALL_BUN = "curl https://bun.sh/install | bash"
|
INSTALL_BUN = "curl https://bun.sh/install | bash"
|
||||||
# Command to run the backend in dev mode.
|
# Command to run the backend in dev mode.
|
||||||
RUN_BACKEND = "uvicorn --log-level critical --reload --host 0.0.0.0".split()
|
RUN_BACKEND = "uvicorn --log-level critical --reload --host 0.0.0.0".split()
|
||||||
# The number of workers to run in production mode by default.
|
|
||||||
NUM_WORKERS = (os.cpu_count() or 1) * 2 + 1
|
|
||||||
# The default timeout when launching the gunicorn server.
|
# The default timeout when launching the gunicorn server.
|
||||||
TIMEOUT = 120
|
TIMEOUT = 120
|
||||||
# The command to run the backend in production mode.
|
# The command to run the backend in production mode.
|
||||||
RUN_BACKEND_PROD = f"gunicorn --worker-class uvicorn.workers.UvicornH11Worker --bind 0.0.0.0:8000 --workers {NUM_WORKERS} --threads {NUM_WORKERS} --preload --timeout {TIMEOUT} --log-level debug".split()
|
RUN_BACKEND_PROD = f"gunicorn --worker-class uvicorn.workers.UvicornH11Worker --bind 0.0.0.0:8000 --preload --timeout {TIMEOUT} --log-level debug".split()
|
||||||
|
|
||||||
# Compiler variables.
|
# Compiler variables.
|
||||||
# The extension for compiled Javascript files.
|
# The extension for compiled Javascript files.
|
||||||
|
@ -8,6 +8,8 @@ import traceback
|
|||||||
from abc import ABC
|
from abc import ABC
|
||||||
from typing import Any, Callable, ClassVar, Dict, List, Optional, Sequence, Set, Type
|
from typing import Any, Callable, ClassVar, Dict, List, Optional, Sequence, Set, Type
|
||||||
|
|
||||||
|
from redis import Redis
|
||||||
|
|
||||||
from pynecone import constants, utils
|
from pynecone import constants, utils
|
||||||
from pynecone.base import Base
|
from pynecone.base import Base
|
||||||
from pynecone.event import Event, EventHandler, window_alert
|
from pynecone.event import Event, EventHandler, window_alert
|
||||||
@ -476,7 +478,7 @@ class StateManager(Base):
|
|||||||
token_expiration: int = constants.TOKEN_EXPIRATION
|
token_expiration: int = constants.TOKEN_EXPIRATION
|
||||||
|
|
||||||
# The redis client to use.
|
# The redis client to use.
|
||||||
redis: Any = None
|
redis: Optional[Redis] = None
|
||||||
|
|
||||||
def setup(self, state: Type[State]):
|
def setup(self, state: Type[State]):
|
||||||
"""Set up the state manager.
|
"""Set up the state manager.
|
||||||
|
@ -29,6 +29,7 @@ from typing import (
|
|||||||
|
|
||||||
import plotly.graph_objects as go
|
import plotly.graph_objects as go
|
||||||
from plotly.io import to_json
|
from plotly.io import to_json
|
||||||
|
from redis import Redis
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from pynecone import constants
|
from pynecone import constants
|
||||||
@ -385,6 +386,20 @@ def run_frontend_prod(app) -> subprocess.Popen:
|
|||||||
return subprocess.Popen(command, cwd=constants.WEB_DIR)
|
return subprocess.Popen(command, cwd=constants.WEB_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
def get_num_workers() -> int:
|
||||||
|
"""Get the number of backend worker processes.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The number of backend worker processes.
|
||||||
|
"""
|
||||||
|
if get_redis() is None:
|
||||||
|
# If there is no redis, then just use 1 worker.
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Use the number of cores * 2 + 1.
|
||||||
|
return (os.cpu_count() or 1) * 2 + 1
|
||||||
|
|
||||||
|
|
||||||
def run_backend(app):
|
def run_backend(app):
|
||||||
"""Run the backend.
|
"""Run the backend.
|
||||||
|
|
||||||
@ -403,7 +418,14 @@ def run_backend_prod(app) -> None:
|
|||||||
Args:
|
Args:
|
||||||
app: The app.
|
app: The app.
|
||||||
"""
|
"""
|
||||||
command = constants.RUN_BACKEND_PROD + [f"{app.__name__}:{constants.API_VAR}"]
|
num_workers = get_num_workers()
|
||||||
|
command = constants.RUN_BACKEND_PROD + [
|
||||||
|
"--workers",
|
||||||
|
str(num_workers),
|
||||||
|
"--threads",
|
||||||
|
str(num_workers),
|
||||||
|
f"{app.__name__}:{constants.APP_VAR}()",
|
||||||
|
]
|
||||||
subprocess.call(command)
|
subprocess.call(command)
|
||||||
|
|
||||||
|
|
||||||
@ -918,20 +940,15 @@ def get_hydrate_event(state) -> str:
|
|||||||
return get_event(state, constants.HYDRATE)
|
return get_event(state, constants.HYDRATE)
|
||||||
|
|
||||||
|
|
||||||
def get_redis():
|
def get_redis() -> Optional[Redis]:
|
||||||
"""Get the redis client.
|
"""Get the redis client.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The redis client.
|
The redis client.
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
import redis # type: ignore
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
|
|
||||||
config = get_config()
|
config = get_config()
|
||||||
if config.redis_url is None:
|
if config.redis_url is None:
|
||||||
return None
|
return None
|
||||||
redis_url, redis_port = config.redis_url.split(":")
|
redis_url, redis_port = config.redis_url.split(":")
|
||||||
print("Using redis at", config.redis_url)
|
print("Using redis at", config.redis_url)
|
||||||
return redis.Redis(host=redis_url, port=int(redis_port), db=0)
|
return Redis(host=redis_url, port=int(redis_port), db=0)
|
||||||
|
Loading…
Reference in New Issue
Block a user