HandleSpecialURL Client Session Thread blocks others?

In a standalone web app I understand that client requests are handled in the HandleSpecialURL event, each one running in it’s own (cooperative) thread. But …

If the code in the HandleSpecialURL is waiting (yes, not good OOP) for another method to finish - ie, a DB query that is possibly slow - does that block the creation of other HandleSpecialURL threads for the other incoming client requests, since the thread code hasn’t looped or exited (so that the threadScheduler can yield time to other threads)?

Is the goal in the SpecialHandleURL event to start another thread (passing the client’s webrequest) and then return true as soon as possible, so as not to block the creation of the other threads?

Then the spawned thread could call back (Using the XojoTask thread and addHandler to map their events to methods in the app class) and then respond back to the client? Or …

Does returning TRUE in the HandleSpecialURL event close the client’s connection, and prevent the spawned thread from being able to still return data to the client?

I’ve written desktop apps using Threads with good success, but I’m new to handling them in the Xojo Web Apps.

I appreciate any tips or suggestions on “Don’t do that, do this instead” … :wink:

I don’T think HandleSpecialURL is written to be multithreaded.

[quote=244758:@Justin Elliott]In a standalone web app I understand that client requests are handled in the HandleSpecialURL event, each one running in it’s own (cooperative) thread. But …

If the code in the HandleSpecialURL is waiting (yes, not good OOP) for another method to finish - ie, a DB query that is possibly slow - does that block the creation of other HandleSpecialURL threads for the other incoming client requests, since the thread code hasn’t looped or exited (so that the threadScheduler can yield time to other threads)?
[/quote]
Using a xojo supplied db plugin SHOULD yield while waiting for the query to complete

Ok. let me clear some things up…

HandleSpecialURL does use the same mechanism as all incoming requests… and they’re all threaded.

That said, requests that are not associated with a session are the only ones that come to HandleSpecialURL and HandleURL. This allows you to intercept things like 404 NOT FOUND errors and the like.

As far as blocking goes, the db plugins should not, but if you run a tight loop without yielding, you certainly could.

Sorry, my fault.

But it’s not built to be asynchronous. So we have to spend time in the method until finished, right?

Let’s put it this way… Typically when creating an API where the operation may take some time, what you do is return a 2xx response and instruct the caller to make additional calls to find out what the progress of the method is. That way you can put this long running process in a thread and have it take as long as it takes.

Also look at the problem that I described here:

https://forum.xojo.com/7793-how-to-keep-the-ui-responsive-during-long-taking-sqlite-queries/p1#p243685

The example does not use handleSpecialUrl, but I think that the result would be the same.

@Greg O’Lone : Ok, should this be doable?

I have around 700 clients that could at any given time request an HTTPS URL from the web app which then does a DB query for each client request. After the DB query has completed the server returns a JSON formatted string for the client to parse. I’m using the PostgreSQLDatabase class for the DB queries.

The DB queries are simple and should be quick, but what I’m seeing is that each client request is being handled one at a time, then on to the next one rather than each request running in a thread and then running multiple DB queries at (close to) the same time.

So far it seems that until each instance of HandleSpecialURL has returned TRUE or FALSE that all other HandleSpecialURL threads are completely blocked. Unless it’s my code (which it could be, still reviewing) this will greatly impact the performance of my web app responding quickly to the flood of client requests at one time.

Are the other HandleSpecialURL threads blocked until the previously created one has exited with a return of TRUE or FALSE? Is what I’m trying to do above a reasonable thing to expect that a standalone Xojo web app should be able to do?

I’m not trying to bash the framework at all, in fact, I’ve had great success with it thus far.

Where are your database connections scoped to?

Are you instantiating a new db object scoped to each HandleSpecialURL thread, or using an App level one?

Scoped to the App level. With the help of @Kem Tekinay this morning it appears that the HandleSpecialURL event (IDE and built app on OS X) only handles 2 connections at a time until the next 2 are serviced.

I’ll work on submitting a feedback on this bug/limitation, unless this is by design?

Justin - we have discussed load balancing already, but routing requests among a group of instances (even on the same physical server) instead of bottlenecking through one instance would make a difference for you here. This works great with HandleSpecialURL because you don’t even have to worry about maintaining session across the load-balancer. I do this exact thing (with XML instead of JSON) in my distribution center API …my .02

Shouldn’t you create a new database connection per HandleSPecialURL event? Using the App level database connection means that you can’t use transactions. This might not be a big deal for your app but it is something to keep in mind.

He already does that, but the observed behavior has nothing to do with a database connection. We tested with a simple, do nothing loop.

Does yielding within the loop make a difference? Xojo has the opportunity to yield on loop boundaries, but is not guaranteed to. Make your “do nothing” loop into a “yield always” loop and see if it makes a difference.

We did. It didn’t.

As said John, we can launch multiple instances. But it is not normal for only a few connections. This adds an additional maintenance fee and an additional requirement of memory. This is a significant cost.

I recommended that @Justin Elliott rewrite this as a console app around ServerSocket because that’s what his web app is really doing. Shouldn’t be any problem with that even with a heavier load considering how quick the connections are.

Please tell us if it works with a console app. If I remember correctly, the web framework is also built on serverSocket (web server work of Thom).

I know from experience that works as we built a middleware app in console and have multiple users connected throughout the day. The SSLSocket receives a raw “message” and starts a thread that decodes, handles, and responds to it. It then starts another thread that encodes the response and sends it.

Remember, the problem here specifically is a limitation in HandleSpecialURL. If Justin were serving actual web pages via sessions, this wouldn’t be an issue.

It would be great to publish a Feedback. Many people use handleSpecialUrl.