ZeroCopy, Chunked Transfer & More by Sartharon · Pull Request #3662 · PhantomBot/PhantomBot
As nowadays files especially video and lossless audio is getting rather larger in size one can observe rather drastic memory allocation when an alert is triggered pointing to such files. The extraordinary memory allocation can be explained by two front sanding factors:
- Only sending
FullHTTPRequeststhus needing to copy the full file into the heap all at once (reading the file) and then from the heap into Netty's own buffersByteBuffer. Thus we hold the file twice in RAM index.js(for alerts) having some logic issues due to browsers pre-loading already thus 2x the required heap will be allocated for a short while until GC can clean the residues of the interrupted first load
My believe is that Phantombot should be using minimal amount of resources which I try to achieve with the following PR.
This PR in short does the following on the alerts side of things:
- Find available audio files to a gif file on the server side. Saving CPU cycles for dealing with the otherwise upcoming
HEADrequests. Available files will be transmitted from the backend to the frontend. The front end will only need to choose what file it will play. - Similar to the above, for
audiohooksthe server compiles an array of available files and the client will choose which one to load and play GifAlertsallows to also play video. Now video playback will be handled in the properhandleVideoClipfunction instead of bloatinghandleGifAlerts- Removed dynamic HTML element creation and deletion as it is error prone and all can be achieved with static HTML elements
- Let the browser deal with the loading of the file (possible to backend changes below)
On the HTTPServer side I did the following:
- Add support for byte ranges opening up modern streaming for files
- Include proper caching headers enabling the browser to use it's cached file instead of constantly hammering Phantombot's backend for the same file over and over (happens often with alerts)
- Add support for chunked file transfers easing some pressure of the memory for larger files.
- Add support for zero-copy (aka.
FileRegion) using the underlying OS to send the file. This reduces CPU cycles and memory to near zero as the OS is instructed to provide the file to the interface buffer for sending. There is absolutely no more userspace copying ongoing (This has plenty of requirements to work. We will revert to Chunked transfers if not all are met) - Only compress files which are worth compressing (Currently only
gzipand deflate but I am happy to addBrotliand/orZstd)