Skip to content

Commit 5c1301b

Browse files
authored
Running ReactPy in a backhaul thread (#163)
- The entirety of the ReactPy rendering stack is encapsulated within a single backhaul thread. - Backhaul thread can be disabled via settings.py:REACTPY_BACKHAUL_THREAD - Implementation is "thread-safe" since all ReactPy code runs on the exact same thread.
1 parent 0aaaaac commit 5c1301b

30 files changed

+751
-109
lines changed

.github/workflows/test-docs.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,4 @@ jobs:
3333
pip install -r requirements/check-style.txt
3434
mypy --show-error-codes docs/python/
3535
black docs/python/ --check
36-
isort docs/python/ --check-only
37-
flake8 docs/python/
36+
ruff check docs/python/

.github/workflows/test-src.yml

+30-30
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
name: Test
22

33
on:
4-
push:
5-
branches:
6-
- main
7-
pull_request:
8-
branches:
9-
- main
10-
schedule:
11-
- cron: "0 0 * * *"
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
schedule:
11+
- cron: "0 0 * * *"
1212

1313
jobs:
14-
source:
15-
runs-on: ubuntu-latest
16-
strategy:
17-
matrix:
18-
python-version: ["3.8", "3.9", "3.10"]
19-
steps:
20-
- uses: actions/checkout@v3
21-
- uses: nanasess/setup-chromedriver@master
22-
- uses: actions/setup-node@v3
23-
with:
24-
node-version: "14"
25-
- name: Use Python ${{ matrix.python-version }}
26-
uses: actions/setup-python@v4
27-
with:
28-
python-version: ${{ matrix.python-version }}
29-
- name: Install Python Dependencies
30-
run: pip install -r requirements/test-run.txt
31-
- name: Run Tests
32-
run: |
33-
npm install -g npm@latest
34-
npm --version
35-
nox -s test
14+
source:
15+
runs-on: ubuntu-latest
16+
strategy:
17+
matrix:
18+
python-version: ["3.9", "3.10", "3.11"]
19+
steps:
20+
- uses: actions/checkout@v3
21+
- uses: nanasess/setup-chromedriver@master
22+
- uses: actions/setup-node@v3
23+
with:
24+
node-version: "14"
25+
- name: Use Python ${{ matrix.python-version }}
26+
uses: actions/setup-python@v4
27+
with:
28+
python-version: ${{ matrix.python-version }}
29+
- name: Install Python Dependencies
30+
run: pip install -r requirements/test-run.txt
31+
- name: Run Tests
32+
run: |
33+
npm install -g npm@latest
34+
npm --version
35+
nox -s test

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ Using the following categories, list your changes in this order:
3434

3535
## [Unreleased]
3636

37-
- Nothing yet!
37+
### Added
38+
39+
- `REACTPY_BACKHAUL_THREAD` setting to enable/disable threading behavior.
40+
41+
### Changed
42+
43+
- By default, ReactPy will now use a backhaul thread to increase performance.
44+
- Minimum Python version required is now `3.9`
3845

3946
## [3.2.1] - 2023-06-29
4047

docs/python/settings.py

+4
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@
2020
# 2. You are using Django's `AUTHENTICATION_BACKENDS` setting and...
2121
# 3. Your Django user model does not define a `backend` attribute
2222
REACTPY_AUTH_BACKEND = None
23+
24+
# Whether to enable rendering ReactPy via a dedicated backhaul thread
25+
# This allows the webserver to process traffic while during ReactPy rendering
26+
REACTPY_BACKHAUL_THREAD = True

docs/src/contribute/code.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
If you plan to make code changes to this repository, you will need to install the following dependencies first:
1414

15-
- [Python 3.8+](https://www.python.org/downloads/)
15+
- [Python 3.9+](https://www.python.org/downloads/)
1616
- [Git](https://git-scm.com/downloads)
1717
- [NPM](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) for installing and managing Javascript
1818

docs/src/contribute/docs.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
If you plan to make changes to this documentation, you will need to install the following dependencies first:
1010

11-
- [Python 3.8+](https://www.python.org/downloads/)
11+
- [Python 3.9+](https://www.python.org/downloads/)
1212
- [Git](https://git-scm.com/downloads)
1313

1414
Once done, you should clone this repository:

docs/src/contribute/running-tests.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This repository uses [Nox](https://nox.thea.codes/en/stable/) to run tests. For
1010

1111
If you plan to run tests, you will need to install the following dependencies first:
1212

13-
- [Python 3.8+](https://www.python.org/downloads/)
13+
- [Python 3.9+](https://www.python.org/downloads/)
1414
- [Git](https://git-scm.com/downloads)
1515

1616
Once done, you should clone this repository:

docs/src/dictionary.txt

+1
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ backends
3535
backend
3636
frontend
3737
frontends
38+
backhaul

noxfile.py

+1-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import nox
77
from nox.sessions import Session
88

9-
109
HERE = Path(__file__).parent
1110
POSARGS_PATTERN = re.compile(r"^(\w+)\[(.+)\]$")
1211

@@ -21,14 +20,6 @@ def manage(session: Session) -> None:
2120
session.run("python", "manage.py", *session.posargs)
2221

2322

24-
@nox.session(reuse_venv=True)
25-
def format(session: Session) -> None:
26-
"""Run automatic code formatters"""
27-
install_requirements_file(session, "check-style")
28-
session.run("black", ".")
29-
session.run("isort", ".")
30-
31-
3223
@nox.session
3324
def test(session: Session) -> None:
3425
"""Run the complete test suite"""
@@ -70,15 +61,14 @@ def test_types(session: Session) -> None:
7061
def test_style(session: Session) -> None:
7162
"""Check that style guidelines are being followed"""
7263
install_requirements_file(session, "check-style")
73-
session.run("flake8", "src/reactpy_django", "tests")
7464
session.run(
7565
"black",
7666
".",
7767
"--check",
7868
"--extend-exclude",
7969
"/migrations/",
8070
)
81-
session.run("isort", ".", "--check-only")
71+
session.run("ruff", "check", ".")
8272

8373

8474
def install_requirements_file(session: Session, name: str) -> None:

pyproject.toml

+8-10
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,6 @@
22
requires = ["setuptools>=42", "wheel"]
33
build-backend = "setuptools.build_meta"
44

5-
[tool.isort]
6-
multi_line_output = 3
7-
force_grid_wrap = 0
8-
use_parentheses = "True"
9-
ensure_newline_before_comments = "True"
10-
include_trailing_comma = "True"
11-
line_length = 88
12-
lines_after_imports = 2
13-
extend_skip_glob = ["*/migrations/*", '.nox/*', '.venv/*', 'build/*']
14-
155
[tool.mypy]
166
exclude = [
177
'migrations/.*',
@@ -22,3 +12,11 @@ warn_redundant_casts = true
2212
warn_unused_ignores = true
2313
check_untyped_defs = true
2414
incremental = false
15+
16+
[tool.ruff.isort]
17+
known-first-party = ["src", "tests"]
18+
19+
[tool.ruff]
20+
ignore = ["E501"]
21+
extend-exclude = ["*/migrations/*", ".venv/*", ".eggs/*", ".nox/*", "build/*"]
22+
line-length = 120

requirements/check-style.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
black
2-
flake8
3-
isort
2+
ruff

requirements/test-env.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ playwright
22
twisted
33
channels[daphne]>=4.0.0
44
tblib
5+
whitenoise

setup.cfg

-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,2 @@
11
[bdist_wheel]
22
universal=1
3-
4-
[flake8]
5-
ignore = E203, E266, E501, W503, F811, N802
6-
max-line-length = 88
7-
max-complexity = 18
8-
select = B,C,E,F,W,T4,B9,N,ROH
9-
exclude =
10-
.eggs/*
11-
.nox/*

setup.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from setuptools.command.develop import develop
1414
from setuptools.command.sdist import sdist
1515

16-
1716
if sys.platform == "win32":
1817
from subprocess import list2cmdline
1918
else:
@@ -22,7 +21,7 @@ def list2cmdline(cmd_list):
2221
return " ".join(map(pipes.quote, cmd_list))
2322

2423

25-
log = getLogger()
24+
log = getLogger() # noqa: F811
2625
log.addHandler(StreamHandler(sys.stdout))
2726

2827

@@ -47,7 +46,7 @@ def list2cmdline(cmd_list):
4746

4847
package = {
4948
"name": name,
50-
"python_requires": ">=3.8",
49+
"python_requires": ">=3.9",
5150
"packages": find_packages(str(src_dir)),
5251
"package_dir": {"": "src"},
5352
"description": "Control the web with Python",
@@ -66,9 +65,9 @@ def list2cmdline(cmd_list):
6665
"Intended Audience :: Developers",
6766
"Intended Audience :: Science/Research",
6867
"Topic :: Multimedia :: Graphics",
69-
"Programming Language :: Python :: 3.8",
7068
"Programming Language :: Python :: 3.9",
7169
"Programming Language :: Python :: 3.10",
70+
"Programming Language :: Python :: 3.11",
7271
"Environment :: Web Environment",
7372
],
7473
}

src/reactpy_django/config.py

+24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from __future__ import annotations
22

3+
import logging
4+
import sys
5+
36
from django.conf import settings
47
from django.core.cache import DEFAULT_CACHE_ALIAS
58
from django.db import DEFAULT_DB_ALIAS
@@ -14,6 +17,9 @@
1417
from reactpy_django.utils import import_dotted_path
1518

1619

20+
_logger = logging.getLogger(__name__)
21+
22+
1723
# Not user configurable settings
1824
REACTPY_DEBUG_MODE.set_current(getattr(settings, "DEBUG"))
1925
REACTPY_REGISTERED_COMPONENTS: dict[str, ComponentConstructor] = {}
@@ -55,3 +61,21 @@
5561
"REACTPY_AUTH_BACKEND",
5662
None,
5763
)
64+
REACTPY_BACKHAUL_THREAD: bool = getattr(
65+
settings,
66+
"REACTPY_BACKHAUL_THREAD",
67+
True,
68+
)
69+
70+
# Settings checks (separate from Django checks)
71+
if (
72+
sys.platform == "linux"
73+
and sys.argv
74+
and sys.argv[0].endswith("daphne")
75+
and REACTPY_BACKHAUL_THREAD
76+
):
77+
_logger.warning(
78+
"ReactPy is running on Linux with Daphne, but REACTPY_BACKHAUL_THREAD is set "
79+
"to True. This configuration is known to be unstable. Either set "
80+
"REACTPY_BACKHAUL_THREAD to False, or run ReactPy with a different ASGI server."
81+
)

0 commit comments

Comments
 (0)