I have a WebSDKUIControl.
In a method called “GetData” (using generic names) I’m using the executejavascript method to run a javascript method client side. I want the “GetData” to return a string. As Web doesn’t have “EvecuteJavascriptSync” you can’t return data inline. And using “triggerServerEvent” fires off the generic “ExecuteEvent”. Which means the “GetData” method finishes before the “ExecuteEvent” fires and can’t be returned.
The only way I can think is to have a loop inside “GetData” and have it pause there until a dictionary is populated from the “ExecuteEvent” event.
Only issue is; SleepCurrentThread and YieldToCurrentThread now cause this unhandled error in Web
Trying to have synchronous methods like this in a WebSDK control (or any part of a Xojo Web app) is going to cause more problems than it solves. Build asynchronously.
Cant in this instance. I would have to split up methods and run the code to populate the variables and then the other half to do the rest of the method.
Other option is storing all data in dictionaries and adding events to all client side changes and storing them. Just seems like it would use a lot of resources keeping the server up to date.
Do you know of a reason why Web doesnt have ExecuteJavascriptSync?
Think its a necessity for WebSDKControls. You cant have the same functionality as Xojo controls otherwise
Do you know of a reason why Web doesnt have ExecuteJavascriptSync?
The way sessions are managed and the single-threaded nature of Xojo is a big one. The last time I tried to do anything synchronous like this – which, granted, was a very long time ago, and just as an experiment – I would see session disconnects, context switches, and other real bad things.
Xojo controls also operate asynchronously. What would make you think otherwise? You can even view the source code for the Xojo Web framework by inspecting Xojo.js in the browser’s developer tools, if you wish. They use the same asynchronous methodology that we are expected to.
Your control should be written so as to not expect or require an immediate response to any given JavaScript command. Send the code to perform whatever function you desire, return any data via ExecuteEvent, deal with that data there then raise your own Event Handler when complete if necessary.
That data is stored in memory on the server. When you call that method, it’s not querying the control in the client-side framework, it’s getting it from the data stored within the app’s memory on the server.
Imagine you have a WebSDKControl with a Text computed property. That Text property has a backing property called mText. When you set myControl.Text = "something", that backing property has its value set to “something”. When you later ask for that value using something like var value = myControl.Text, the framework isn’t asking the client what the value of Text is, it’s getting the value of mText.
Thats what i thought but was hoping there would be a less intensive way than client side spamming ajax calls. The control I’m making has a lot of client side javascript to take the load off and make it more responsive. Im probably going to have to go with the storing data way. Was trying to be more efficient.
Hopefully one day Xojo is able to implement threads instead of fibers and then each session can be on its own thread
I don’t see a move from asynchronous operation to synchronous operation being likely (or, I’d argue, advisable) in the current tech landscape. The web is an asynchronous world. Whether it be due to frequent disconnects, slow connection speeds, or a myriad of other factors, it’s just not something that’s easily or reliably done. Node.js and other such frameworks have more or less the same limitations for the same reasons.
If each session was on its own thread then you would only be pausing the 1 session. Obviously it would have to have a timeout small enough to not disconnect a session and cause weird UI hang-ups.
I get why Xojo don’t let users create threads (they call them threads but they’re really fibres) but the compiled program could use threads. Main thread for App, another thread for message queue, single thread for each session. I used this architecture in a DLL I wrote. Needed a message queue so I could talk back to Xojo on a single thread as multi threaded messaging was causing Xojo crashes. This way a Xojo application could handle way more sessions and sessions wouldn’t impact on other sessions performance. A session could then have synchronous operations but with a forced timeout
@Liam_Sawrey
From the guy who worked on web 1 for seven years and then created web 2, you should reconsider your position and do everything asynchronously. Regardless of whether Xojo ever does preemptive threads, handling things async gets you a lot more mileage in the long run.
What you’re not considering here is that it’s not just the sessions that would have to be threaded but also the web server itself because right now, all socket events fire on the mail thread as well. There’s also no guarantee that you wouldn’t get two requests (and therefore two sockets) for the same session at the same time.
The last part of the issue is that Xojo’s frameworks are not thread safe. The amount of time and effort it would take to do that and to maintain it in contrast with the number of people who really need and would use preemptive threading is unlikely to be cost effective. Not to mention the tech support calls they’d have to field from users who don’t understand why their apps keep crashing when they design something that’s not thread-safe. There are just some things that Xojo cannot protect you from and not understanding thread safe-ness is one of them.
Do yourself a favor, take the advice from me and Anthony and refactor your app to be asynchronous. Your app will behave better in the long run and you’ll learn an invaluable skill that will serve you well on all modern OSes.
Of course I will do everything asynchronously. Was just a wish to not.
I wasn’t talking about giving the users pre-emptive threading but Xojo making the backend threaded. Would allow better scaling of apps and eliminate long running code on one session affecting another.
FWIW, unless there’s been a complete rewrite of the back end since I left, Sessions are already threaded using Xojo’s cooperative threading model today.
But you can do this yourself today… just use a WebThread yourself for long running processes and tell it to yield periodically.