Fix websocket race condition (#261)
This commit is contained in:
parent
c8936355f2
commit
1e64e62842
@ -1 +1 @@
|
|||||||
0.1.12
|
0.1.13
|
@ -96,12 +96,13 @@ export const applyEvent = async (event, router, socket) => {
|
|||||||
/**
|
/**
|
||||||
* Process an event off the event queue.
|
* Process an event off the event queue.
|
||||||
* @param state The state with the event queue.
|
* @param state The state with the event queue.
|
||||||
|
* @param setState The function to set the state.
|
||||||
* @param result The current result
|
* @param result The current result
|
||||||
* @param setResult The function to set the result.
|
* @param setResult The function to set the result.
|
||||||
* @param router The router object.
|
* @param router The router object.
|
||||||
* @param socket The socket object to send the event on.
|
* @param socket The socket object to send the event on.
|
||||||
*/
|
*/
|
||||||
export const updateState = async (state, result, setResult, router, socket) => {
|
export const updateState = async (state, setState, result, setResult, router, socket) => {
|
||||||
// If we are already processing an event, or there are no events to process, return.
|
// If we are already processing an event, or there are no events to process, return.
|
||||||
if (result.processing || state.events.length == 0) {
|
if (result.processing || state.events.length == 0) {
|
||||||
return;
|
return;
|
||||||
@ -112,25 +113,34 @@ export const updateState = async (state, result, setResult, router, socket) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the next event in the queue.
|
// Set processing to true to block other events from being processed.
|
||||||
setResult({ ...result, processing: true });
|
setResult({ ...result, processing: true });
|
||||||
await applyEvent(state.events.shift(), router, socket);
|
|
||||||
|
// Pop the next event off the queue and apply it.
|
||||||
|
const event = state.events.shift()
|
||||||
|
|
||||||
|
// Set new events to avoid reprocessing the same event.
|
||||||
|
setState({ ...state, events: state.events });
|
||||||
|
|
||||||
|
// Apply the event.
|
||||||
|
await applyEvent(event, router, socket);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to a websocket and set the handlers.
|
* Connect to a websocket and set the handlers.
|
||||||
* @param socket The socket object to connect.
|
* @param socket The socket object to connect.
|
||||||
* @param state The state object to apply the deltas to.
|
* @param state The state object to apply the deltas to.
|
||||||
|
* @param setState The function to set the state.
|
||||||
* @param setResult The function to set the result.
|
* @param setResult The function to set the result.
|
||||||
* @param endpoint The endpoint to connect to.
|
* @param endpoint The endpoint to connect to.
|
||||||
*/
|
*/
|
||||||
export const connect = async (socket, state, result, setResult, router, endpoint) => {
|
export const connect = async (socket, state, setState, result, setResult, router, endpoint) => {
|
||||||
// Create the socket.
|
// Create the socket.
|
||||||
socket.current = new WebSocket(endpoint);
|
socket.current = new WebSocket(endpoint);
|
||||||
|
|
||||||
// Once the socket is open, hydrate the page.
|
// Once the socket is open, hydrate the page.
|
||||||
socket.current.onopen = () => {
|
socket.current.onopen = () => {
|
||||||
updateState(state, result, setResult, router, socket.current)
|
updateState(state, setState, result, setResult, router, socket.current)
|
||||||
}
|
}
|
||||||
|
|
||||||
// On each received message, apply the delta and set the result.
|
// On each received message, apply the delta and set the result.
|
||||||
|
@ -162,10 +162,11 @@ READY = f"const {{ isReady }} = {ROUTER};"
|
|||||||
USE_EFFECT = join(
|
USE_EFFECT = join(
|
||||||
[
|
[
|
||||||
"useEffect(() => {{",
|
"useEffect(() => {{",
|
||||||
" if(!isReady)",
|
" if(!isReady) {{",
|
||||||
f" return;",
|
f" return;",
|
||||||
|
" }}",
|
||||||
f" if (!{SOCKET}.current) {{{{",
|
f" if (!{SOCKET}.current) {{{{",
|
||||||
f" connect({SOCKET}, {{state}}, {RESULT}, {SET_RESULT}, {ROUTER}, {EVENT_ENDPOINT})",
|
f" connect({SOCKET}, {{state}}, {{set_state}}, {RESULT}, {SET_RESULT}, {ROUTER}, {EVENT_ENDPOINT})",
|
||||||
" }}",
|
" }}",
|
||||||
" const update = async () => {{",
|
" const update = async () => {{",
|
||||||
f" if ({RESULT}.{STATE} != null) {{{{",
|
f" if ({RESULT}.{STATE} != null) {{{{",
|
||||||
@ -179,7 +180,7 @@ USE_EFFECT = join(
|
|||||||
f" {PROCESSING}: false,",
|
f" {PROCESSING}: false,",
|
||||||
" }})",
|
" }})",
|
||||||
" }}",
|
" }}",
|
||||||
f" await updateState({{state}}, {RESULT}, {SET_RESULT}, {ROUTER}, {SOCKET}.current)",
|
f" await updateState({{state}}, {{set_state}}, {RESULT}, {SET_RESULT}, {ROUTER}, {SOCKET}.current)",
|
||||||
" }}",
|
" }}",
|
||||||
" update()",
|
" update()",
|
||||||
"}})",
|
"}})",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "pynecone-io"
|
name = "pynecone-io"
|
||||||
version = "0.1.11"
|
version = "0.1.13"
|
||||||
description = "The easiest way to build web apps."
|
description = "The easiest way to build web apps."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
authors = [
|
authors = [
|
||||||
@ -53,3 +53,5 @@ pc = "pynecone.pc:main"
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
[tool.pyright]
|
Loading…
Reference in New Issue
Block a user