TCPSocket.Connect causes UI to hang on slow connection

I have a desktop application running on a Raspberry Pi with a Websocket connection to a backend server over satellite internet.

The Websocket client is a subclass of TCPSocket and uses TCPSocket.Connect, TCPSocket.Write, and TCPSocket.DataAvailable to exchange data. TCPSocket.Connect is called from a Thread.Run event which is executed in a Timer.Action event. When the Websocket client tries to connect there is a brief hang of the UI (4-5seconds sometimes more) where no events are handled, buttons cannot be clicked and timers do not run. I assume that TCPSocket.Connect is blocking the main thread and causing no events to be processed. I tried using Network Link Conditioner on my Mac but the effect is not very noticeable even with 4000ms+ of latency.

I thought I remember reading somewhere that TCPSocket.Connect is synchronous? Does anyone have an idea of where to start? Is there a reason this is an issue on the Raspberry Pi and not my Mac?

Thanks!

Is there a particular reason to do the .Connect in a Timer.Action event, rather than simply in the thread code? The .Action event code will be running on the main thread.

There is an issue on Raspberry Pi where Thread.Sleep uses 100% CPU (feedback://showreport?report_id=56420). To get around this I have a subclass of Timer that calls Thread.Run so the thread only runs when it needs to. The TCPSocket.Connect method is called from the thread.

I have noticed that if you’re using a DNS name as opposed to an IP address it can hang if the lookup is very slow. The actual connections and other handling seem to be very fast, though if you process the data available in the main thread that could also hang the main thread and therefore the UI but thats not been a problem for me.

Are you using a DNS name to connect? If so just as an experiment you could try entering the IP and see if the problem goes away. If thats it there are numerous other ways to do an async DNS lookup from the MBS plugins or even parsing the output from a shell running dig or something similar.

1 Like

Now that you mention it, I think my issue might be “System.Network.LookupIPAddress” This appears to block the main thread even if done in a separate thread. My Mac appears to cache the DNS lookup where the Raspberry Pi and/or satellite modem/router does not. I switched to using Shell but it also blocks the main thread when in mode 0. I am not able to use asynchroness shells as they cause a huge memory leak ( feedback://showreport?report_id=60908). I have now made a global async shell that never stops and just takes commands and waits for the response. This emulates a synchroness shell but in the context of the thread it was executed on. Bit of a wild workaround but I guess its as good as we can do while we wait for a fix for Thread.Sleep issue and/or the async Shell memory leak issue.

1 Like

I’ve added some points to that bug report as I use a lot of async shells in other projects and wasn’t even more than vaguely aware of that. Normally I start them up just once or twice for each specific task and keep them running the whole time but that can be a long time measured in weeks or even months, if there are other leaks associated with that then I also want that fixed!

There are MBS plugin methods to do an sync lookup I’m fairly certain if you have access to those it might be another way to go.

Thank you, I use async shells to poll for information from files as Xojo file IO is blocking. At 100 calls per minute or more I was running out of memory in less than half an hour. This system is expected to run continuously for a long time without restarts so memory management is very important.