Faster GlobalBufferAsyncJsonResponse#3748
Conversation
Rather than hold the lock through the entire response process, serialize the result completely when the initial packet buffer is filled, and then release the lock. Allocate only enough extra memory to hold the part of the serialized response that can't go directly to the output packet buffer.
|
Since you are rewriting |
|
This implementation uses the global JSON document, so it'll follow the same PSRAM behavior of the global document. If you're suggesting that we could store the serialized JSON in PSRAM too: yes, that's probably a good call. I should likely pick up a PSRAM board for testing. |
|
I did consider outright replacing Annoyingly the other immediately available approach -- serialize to a |
|
This PR isn't the same as the other locking fixes: this one is about storing the serialized JSON output in the web response, but using a chain of small buffers instead of serializing to a large contiguous buffer, to allow faster memory recovery and be more resistant to fragmentation. The major advantage is better support for parallel web requests, particularly for ESP32s which are not so RAM limited, but implemented with an eye on keeping ESP8266es stable. I'd opened this draft PR to get your feedback early on the overall idea of serializing early rather than holding the lock. Unfortunately I think the specific patch here is more confusing than anything else. As an artifact of my particular development path, the buffering changes were mixed in with the locking logic. Further, as I've spent more time with the web server code, I've learned that there's basically no value in doing early serialization in the response object. The first output packet will be generated immediately after the handler function is called. So if we do want to do early serialization, it can be done much more clearly directly in the handler function. (In fact, doing so would eliminate the need for holding the lock in the response object altogether!) All of this said: I agree we should close this PR - it can be considered obsolete as I'm implementing buffer list support in the web server repo. I'll open PRs with better targeted changes to WLED once that's ready. |
For early review of the approach, this is intended to be better version of #3743, but there are still some TODOs and bugs to work out.
Rather than hold the JSON buffer lock until the entire request is done, serialize the request completely on when the network stack fills the first outgoing packet buffer. We split the serialized response data between the packet buffer and heap-allocated secondary buffer (if one is needed). After serialization, release the JSON document for reuse.
The key insights in this approach is that
request->send()beforeserveJsoneven returns, so the scoping of the JSON buffer lock is so small it can't collide.