I have a simple Xojo webap built with Xojo 2018r4, depolyed as a 64 bit macOS standalone SSL app.
Even though I was running it with 400 or even 600 sockets, it performance falls apart when I had more than 20 simultaneous users. It felt like something was going on worse than just running out of sockets.
From the 2019R1 and R1.1 release notes:
My question: could any of the problems I was seeing in 2018R4 be due to any of these socket-relaed issues?
Has anyone done performance testing on a web app from 2018 to 2019 and seen improvements?
The # of open sockets is unlikely to be the performance issue
The fact that a Xojo app only utilizes a single core and cooperative threading will be
Its why so frequently you see people running several instances behind load balancers like nginx etc
The thing is, the performance seems neither CPU nor Networking limited - it works fine with up to a dozen simultaneous users, but at some point when I have 20+ it just falls apart.
The app runs a simple “survey” - open a webPage, a timer fires which shows an image and some radio buttons, the user clicks a to select an answer then they click another buton to move on to the next question, repeat.
Images are fairly small, and there’s not much going on computationaly.
It’s for a class I teach - a mix of mac + windows users with whatever browser they preferred, so it’s a good real-world test case, but not one I can reproduce easily.
Last time it happened:
Some users had normal operation
Other users seemed to get stuck: typically they would see some parts of the page (a few text labels and buttons) but some parts (usually the image) would never load.
It seemed like it was worse on some browsers and better on others (from memory, Safari IE11 and Edge were doing better than Chrome, but I couldn’t swear to that)
On the server, CPU and memory usage of the WebAPp was low
The webApp has good logging for exceptions, and there were none seen.
If the WebApp CPU use was high, I could see this just being a “too many users” problem, but that’s not what it looked like at all.
youre not using anything that could be using the disable background tasks pragma? Or doing any database signons or such things that are blocking? There are other things that are blocking too, Im fairly sure that file access is blocking for all threads until its done and probably lots of system related things. Stack up enough of such things and it would definitely start to degrade performance for all the different threads. When youre serving up the images or other static resources are you caching them in memory or loading them and sending them each time? Im not completely sure if the standard webFile and webImage things keep the data in memory once its loaded but I think they do. But if youre creating a new one for each session then youre going to run into that disk access as something that slows down the other threads, I always just set their session to nil so that they will work on any session and keep a global list of such things to serve to all sessions so that I only create it once.
No database, no blocking calls of any significant duration.
The images are loaded once by the app, and then simply copied/cloned as WebPictures for each session. There is a little inefficiency here as the images start as JPGs but then are converted to WebPicture (which I believe uses PNGs). Worst case they’d end up about 0.5MB each, and this is on a 2MB/s connection, so serving up 40 of them would take ~10 seconds. But the behavior isn’t consistent with this (e.g. the CPU is not maxxed out nor is the internet connection saturated), and the images aren’t just slow to load, they never load.
I’m going to rebuild it in 2019R1.1 and test it out this week, and will report back. I’m going to try to do as much monitoring as I can (watching the bandwidth on the router, CPU and maybe taking some Samples of the webApp itself if the stall happens).
App. I’m monitoring using ActivityMonitor (which gives same numbers as ‘top’) in which 100% would mean one core was maxxed out. Since this is a single-threaded app, 100% would be the most possible. It’s more like 5-10%.
Also, I just checked and the actual PNGs after conversion are about 150KB each (not 500KB), suggesting the WebApp should be able to serve up over 10 of them per second on my internet connection.
And this is not a case where I have 40 students all hitting the button simultaneously: I give them the URL and it probably takes 1-3 minutes for all of them to get connected, so their requests for images are spread out over a couple of minutes.
Again, the behavior is not “slow but works eventually for all users” but “some users get normal operation, other users seem to get hung”.
If I had to guess, it’s almost as if for some users, their WebTimers are never firing, so the request to load the image just never happens.
I’m not entirely sure of the school’s setup, but it’s probably:
Student Computers <---> Ethernet <---> School Router (NAT) <--> Internet <---> My Router (NAT) <---> My Server
There could be something else going wrong - perhaps the NAT translation table is overflowing on one end?
Is there wireless networking involved? Cheap ones can cause problems if too many people jump on at once. The use of Web timers is chatty so any network problems might hit them first.
We use server-side timers (ordinary Timer controls with WebSessions or threading with sleeps) to push images and we test to see if the load has completed. This seems more reliable than relying on timers in browsers across choppy networks under a remote-trigger model.
Wireless: almost every student was using the classroom computers on ethernet.
Apache: no, this is standalone web-app mode Deployment overview — Xojo documentation I am using SSL which is why I mentioned “32344 Framework » All The buffer size on SSLSocket has been increased to 256K.”
Logging: I am doing extensive logging from the webApp, but I’d have to dig into the logs to figure out what went wrong.
I’ll do my IRL test on Thursday using 2019R1.1. I’ll report back and save all the logs so if there is still a problem, I can ID it.
Success! My WebApp built with 2019R1.1 semed to handle multiple users (about 30 simultaneous) without any trouble at all.
I can’t say for sure that the Xojo 2019 upgrade is the deciding factor (the school network could have changed, Safari and Chrome and Edge browsers may have had updates, etc.) but I think if you are having capacity issues on a Xojo WebApp built with 2018 or earlier, it’s worth giving 2019 a try.