I would never use a synchronous call for anything but the simplest requests. The fact that someone with 8 servers was using synchronous sockets in threads tells me they were not coding properly! It’s fairly easy to create a handler for the finished result of the asynchronous calls. Performance is way mo betta!

1 Like

The key is each request was inside its own thread. That should work fine. The issue I believe is they aren’t yielding enough time. The blog post has all the details.

Ooops, Thom! It was you who wrote that code. :face_with_hand_over_mouth:

Did you mean me? Or do I ignore some Eric here inadvertently?
If so: Never mind, and thanks! As a hint: I built a URLConnection subclass too where I can add a tag, and which does time/speed measurements for me. The tag makes it much easier to respond to different replies you are expecting.

Ulrich - yes. Typo on my fat fingers. :slight_smile:

Heh, don’t worry.

1 Like

But if you are putting it in a thread, isn’t running asynchronously just as easy?

Not if I want the effect of synchronous code.

I don’t think so. A synchronous method is not meant to be used pseudo-asynchronously, especially because of the nature of Xojo’s threads. That’s why Christian created some MT methods for similar tasks – synchronous calls which you can use inside a Xojo thread because they are designed to yield.
A URLConnection.SendSynch is not designed to yield, even more if you read the notes on the possibility of GUI freezes.

The GUI freeze would come from using it on the main thread. SendSync does yield on a thread, but not often enough.

I’m not sure which MT methods you mean, but if you mean the PerformMT methods on the cURL classes, those unfortunately aren’t performant enough either. I wish they were because I’d love to kick URLConnection to the curb, but they aren’t. See Improve threading for main thread?

I’ll note that I don’t recall what I tried with CURLSMultiMBS.

I don’t see how that should possible. Maybe @Christian_Schmitz or some engineer could jump in?
SendSync means “Send the request and only return when you got the result (or error/timeout).” That is valid on any thread. If you have the feeling that SendSync yields when used on a thread, it must be some internal magic because the scheduler should be frozen until SendSync returns.

By what I mean to read from the docs, I think that you try tricks the class is not designed for. And yes, I meant something like CURLSMBS. Even here, I am not sure if both performance and the approach you are looking for is possible. Although PerformMT yields, I doubt that several instances of it can technically compete with an asynchronous method. But again, maybe Christian can confirm.

Plenty of classes have the ability to yield time to other threads. Even if URLConnection is pure Xojo code - which I don’t think it is - the SendSync method could look something like

While Not Finished
  If (App.CurrentThread Is Nil) = False Then
  End If

That’s it, synchronous effect inside the thread, yielding to other threads while doing its work. Of course, this is a GROSS oversimplification of what’s happening inside SendSync. The point is yielding is not hard at all. The issue is the amount of sleeping.

A good example is SQLiteDatabase. See https://documentation.xojo.com/api/databases/sqlitedatabase.html#sqlitedatabase-threadyieldinterval. In that class you can specify the amount of yield time… though it’s not obvious exactly what the value means. It’s not an amount of time, it’s a number of instructions. But how many operations is right? Regardless, that is an operation that works synchronously but can still yield. It’s not magic.

I get the idea of a synchronous flow for easier code-ability. But Xojo does nothing synchronous well. I’ve forced myself over the years to figure out rather complex ways of taking a synchronous set of steps and handling them asynchronously. It’s a challenge. In the case of the URLConnection, I simply continued my code in a method called by the finished event or whatever the event is that fires when the result is returned.

In your case with a thread, it would be really easy to create a subclass of URLConnection and use an asynchronous call but turn it synchronous. Create a function that will make the call and return the value. Store the returned value in a property. As long as that property is Nil or “” then you don’t have the result. Put checking for the result in a loop inside your “synchronous” method. Check the value of the property each time through the loop. Sleep the thread for whatever you want. Then when it wakes up continue the loop, etc.

Seems like now you would have the best of both worlds.

I’ll write some code for it if you like.

I’m not trying to be rude, but if you read the link, you’d see it was more than just me complaining. I have a solution:

So here’s the gist of what I did to solve the problem. I switched (again) to a subclass of URLConnection called SychronousHTTPSocket. I’ve used this class in the past, and it used to be a subclass of Xojo.Net.HTTPSocket, which never had a way to execute synchronously. So the Send method was overridden to make the request as normal, but then immediately pause the current thread. The pause is important, as we really don’t want the thread doing anything until complete. Calling this on the main thread would logically be an exception.

Then in the PageReceived and Error events, I set some properties for the response to later be retrieved by the calling thread, then resume the thread. This is accomplished by storing a reference to the original calling thread, otherwise we’d always try to resume the main thread. Once the thread resumes, it moves out of the Send method where the calling code can read the results from the properties.

This works great because with the thread paused, it’s not even considered during the event loop, and the URLConnection polling happens on the main thread exactly as normal. I made a special build for the user to confirm, and the timing could be measured in seconds instead of minutes!

The post also includes a link to the class I’m using.

That was the point of linking to the post. “If you try this, you’ll have a bad time, so here’s a solution.” I included the quote because Xojo’s rules don’t like linking off-site, so I’m trying to be as adherent as makes sense. I don’t think quoting the blog post helped in this case.

You aren’t being rude. I did read the blog post a couple hours ago but I did not look at the code and frankly I forgot you basically did what I was suggesting. My fault for not remembering that!

I guess I was just saying that it’s a pretty simple thing to do it like you did.

URLConnection does seem to be a better all round class for accessing HTTP resources. I’ve still been using the classic HTTPSocket as a lot of my stuff is synchronous (REST requests to services that often send little back other than {“result”:“success”} so easily handled as a sync request. Performance has been fine. It’s only since pulling from HTTPS resources that URLConnection makes things easier.

It does seem that sync requests on URL are more resource hogging. The old ones seemed to yield nicely.

Ideally everything would be async but a lot of my code is for driving sequences of events that have to run in order and are dependant on previous results so I’ve done them as a thread running sync events.

I get the leaning toward exception based error handling, it does make for more carefully considered code. I do prefer the older way of working though.

@Ulrich_Bogun I’ve got something similar going on, with a central set of classes that handle the network connections for other calls so changing things is only done in once place. Going to try and adapt around the newer way of working…

James - It’s pretty easy to create a synchronous socket using a thread and asynchronous calls. You might have better luck doing that than with Xojo’s resource hogging synchronous methods.

I’ve pretty much abandoned the old HTTPSocket as it is only HTTP1.0 compliant and most sites won’t work with it particularly if you are using HTTPS calls…

Thanks Jon. Do you mean by making the thread sleep until the reply comes and then on thread completion it hands back to main process?

It’s the vague nature of the REST replies which are a pain. The “result:success” ones aren’t helpful, hence why I’ve stuck to sync. I could create a queue of requests to keep them matched.