Repository navigation
Don't send to the websocket from the caller's task - #100
Merged
Merged
Conversation
Serial_2_Socket::write runs in Marlin's loop task and sent the buffer from there when it filled. Sending to a client that has stopped reading waits up to about 15 s (WiFiClient write retries plus the WebSockets TCP timeout), long enough to trip Marlin's task watchdog. write() now only copies into the TX buffer, under a mutex, and drops output that doesn't fit. flush() only sets a flag. The ESP3DLib task sends the buffer from handle_flush(), to each client in turn, and disconnects a client whose send fails so it can't stall later sends.
Owner
|
Merged - thank you |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Serial_2_Socket::write()is called by Marlin, from Marlin's loop task. When the TX buffer filled, or 500 ms after the first byte, it calledflush(), which sent the buffer withbroadcastBIN()from that task.Sending to a websocket client that has stopped reading blocks. With a full TCP send buffer,
WiFiClient::write()waits up to 10 × 1 s inselect(), andWebSockets::write()keeps retrying for up toWEBSOCKETS_TCP_TIMEOUT(5 s). Marlin's loop task stops for that time. Marlinbugfix-2.1.xwatches that task with a 4 s task watchdog (USE_WATCHDOG, MarlinFirmware/Marlin#28725), so the board resets. A browser tab left open on a phone that has gone to sleep, or a client that dropped off the WiFi, can do this during a print.This PR keeps all network sending in the ESP3DLib task:
write()only copies into the TX buffer, under a mutex. Output that doesn't fit in the buffer is dropped.flush()only sets a flag.handle_flush(), called fromWeb_Server::handle()in the ESP3DLib task, sends the buffer when the flag is set, when it is half full, or afterFLUSHTIMEOUT. It copies the buffer out under the mutex, then sends to each connected client withsendBIN(). A client whose send fails is disconnected, so it can't stall every later send.Testing
MKS TinyBee, Marlin
bugfix-2.1.x(mks_tinybee, arduino-esp32 1.0.6),ESP3D_WIFISUPPORT,WEBSUPPORT,USE_WATCHDOG, station mode. A script sentM503to/commandevery 0.3 s andM118over USB serial every 0.5 s. A test websocket client on port 81 completed the handshake and then never read.M503flood, 60 sloopTask) about 27 s inM118answered in 0.06 s or lessM118andM503output received