Skip to content

Commit fbdd048

Browse files
committed
v3.3.2
1 parent 36da02e commit fbdd048

File tree

4 files changed

+33
-26
lines changed

4 files changed

+33
-26
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ Using the following categories, list your changes in this order:
3636

3737
- Nothing (yet)!
3838

39+
## [3.3.2] - 2023-08-09
40+
41+
### Changed
42+
43+
- Changed implementation of `REACTPY_BACKHAUL_THREAD` to attempt increased performance compatibility.
44+
3945
## [3.3.1] - 2023-08-08
4046

4147
### Added

docs/python/settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@
2727
# 3. Your Django user model does not define a `backend` attribute
2828
REACTPY_AUTH_BACKEND = "django.contrib.auth.backends.ModelBackend"
2929

30-
# Whether to enable rendering ReactPy via a dedicated backhaul thread
31-
# This allows the webserver to process traffic while during ReactPy rendering
30+
# Whether to enable rendering ReactPy via a dedicated backhaul thread.
31+
# This allows the webserver to process traffic while during ReactPy rendering.
3232
REACTPY_BACKHAUL_THREAD = False

src/reactpy_django/checks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def reactpy_warnings(app_configs, **kwargs):
9797
)
9898

9999
# Check if REACTPY_WEBSOCKET_URL doesn't end with a slash
100-
REACTPY_WEBSOCKET_URL = getattr(settings, "REACTPY_WEBSOCKET_URL", "")
100+
REACTPY_WEBSOCKET_URL = getattr(settings, "REACTPY_WEBSOCKET_URL", "reactpy/")
101101
if isinstance(REACTPY_WEBSOCKET_URL, str):
102102
if not REACTPY_WEBSOCKET_URL or not REACTPY_WEBSOCKET_URL.endswith("/"):
103103
warnings.append(

src/reactpy_django/websocket/consumer.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import asyncio
66
import contextlib
77
import logging
8-
from concurrent.futures import Future
98
from datetime import timedelta
109
from threading import Thread
1110
from typing import Any, MutableMapping, Sequence
@@ -41,12 +40,12 @@ class ReactpyAsyncWebsocketConsumer(AsyncJsonWebsocketConsumer):
4140

4241
async def connect(self) -> None:
4342
"""The browser has connected."""
44-
from reactpy_django.config import REACTPY_AUTH_BACKEND, REACTPY_BACKHAUL_THREAD
43+
from reactpy_django.config import REACTPY_AUTH_BACKEND
4544

4645
await super().connect()
4746

4847
# Authenticate the user, if possible
49-
user: Any = self.scope.get("user")
48+
user = self.scope.get("user")
5049
if user and user.is_authenticated:
5150
try:
5251
await login(self.scope, user, backend=REACTPY_AUTH_BACKEND)
@@ -77,33 +76,36 @@ async def connect(self) -> None:
7776
)
7877

7978
# Start the component dispatcher
80-
self.dispatcher: Future | asyncio.Task
81-
self.threaded = REACTPY_BACKHAUL_THREAD
82-
if self.threaded:
83-
if not backhaul_thread.is_alive():
84-
await asyncio.to_thread(
85-
_logger.debug, "Starting ReactPy backhaul thread."
86-
)
87-
backhaul_thread.start()
88-
self.dispatcher = asyncio.run_coroutine_threadsafe(
89-
self.run_dispatcher(), backhaul_loop
90-
)
91-
else:
92-
self.dispatcher = asyncio.create_task(self.run_dispatcher())
79+
self.recv_queue: asyncio.Queue = asyncio.Queue()
80+
self.dispatcher = asyncio.create_task(self.run_dispatcher())
9381

9482
async def disconnect(self, code: int) -> None:
9583
"""The browser has disconnected."""
9684
self.dispatcher.cancel()
85+
await self.dispatcher
9786
await super().disconnect(code)
9887

9988
async def receive_json(self, content: Any, **_) -> None:
10089
"""Receive a message from the browser. Typically, messages are event signals."""
101-
if self.threaded:
102-
asyncio.run_coroutine_threadsafe(
103-
self.recv_queue.put(content), backhaul_loop
104-
)
105-
else:
106-
await self.recv_queue.put(content)
90+
await self.recv_queue.put(content)
91+
92+
async def dispatch(self, message):
93+
"""Override the Django Channels dispatch method to allow running the ASGI
94+
dispatcher in a thread."""
95+
from reactpy_django.config import REACTPY_BACKHAUL_THREAD
96+
97+
if REACTPY_BACKHAUL_THREAD:
98+
if not backhaul_thread.is_alive():
99+
await asyncio.to_thread(
100+
_logger.debug, "Starting ReactPy backhaul thread."
101+
)
102+
backhaul_thread.start()
103+
104+
return asyncio.run_coroutine_threadsafe(
105+
super().dispatch(message), backhaul_loop
106+
).result()
107+
108+
return await super().dispatch(message)
107109

108110
async def run_dispatcher(self):
109111
"""Runs the main loop that performs component rendering tasks."""
@@ -117,7 +119,6 @@ async def run_dispatcher(self):
117119
dotted_path = scope["url_route"]["kwargs"]["dotted_path"]
118120
uuid = scope["url_route"]["kwargs"]["uuid"]
119121
search = scope["query_string"].decode()
120-
self.recv_queue: asyncio.Queue = asyncio.Queue()
121122
connection = Connection( # For `use_connection`
122123
scope=scope,
123124
location=Location(

0 commit comments

Comments
 (0)