Browser Update During Long Process

I generally have had good luck starting a Progress Wheel then launch a long process (maybe 5-10 seconds) in a Single Shot Timer. The Progress Wheel starts before the long process and then when the long process ends it hides the Progress Wheel.

But now I have a very long running process that can take as much as 2 minutes to complete and the Progress Wheel just does not give enough feedback to the user that maybe the process is hung.

I tried putting a counter in the long running process and then displaying that counter in a one second timer but of course the browser is never updated until the long running process completes.

Without breaking the long process into parts is there a way with threads and/or timers to get the browser to update a counter?

Thanks.

Yup, the same approach as doing it on desktop works.
Thread writes values to property, timer reads property and sends to interface OR use the event driven threading method.

I would recommend you separate the thread processing from the interface updating, as it’s easier to keep a track of what’s doing whom; but full disclaimer it isn’t necessary at the moment to follow thread safe ui practices with the Web framework.

Note that contrary to Desktop, threads can access the UI.

I originally tried to use a thread (way back when) and discovered that there was no access to the session without declaring some “session stuff” (I would need to dig out the details). Because it felt a little “clunky” I avoided threads and found timers worked just fine. With a short running processes a little spinner did a good job of communicating that things were still running and I could start the spinner then do the work in a one shot timer.

With this longer running process, for the most part, I can avoid session properties if I put the logic in a thread EXCEPT that the database is opened in the Session Open event.

So I guess I better dig out the code to connect to the session from a thread.

Personally if you are actually talking 2 minute background operations I would break that into a separate executable. Your web UI is going to be very unresponsive in general (especially as more users use it) if background threads are doing heavy operations. Xojo does not have pre-emptive multitasking so this is not an optimal scenario. I’d take your background task and convert it into a separate console application. Call it from your web app using the Shell class. Your console app can output progress information every so often and your web app can read that and update the web UI accordingly.

I am going to append to this one caveat: If you are load balancing several standalone instances behind the scenes then heavy long running tasks is probably OK. Your general run of the mill CGI uploaded app though is going to handle this very poorly.

I thought about creating a console app I could launch from the Web app but the result is an Excel spreadsheet so I would have to create a method to download the output from the console app when it was complete.

One other choice would be to create a desktop app. This is a process that only runs occasionally (maybe once each quarter) but it needs to be run outside of our network. The one user that uses this output sometimes does it from home on a weekend.

This is not urgent so I have some time to play with various solutions.

Why not just write the spreadsheet to the file system? Then your web app could pick it up and present it to the user as a download.

That is what I do now in the Web app. I would do the same in the console app but I just need to communicate back to the user when it is done. I probably could just email them a link and they could download it.

The user is happy to wait a few minutes for it to complete so the email link would be fine.

[quote=335092:@Mark Strickland]I originally tried to use a thread (way back when) and discovered that there was no access to the session without declaring some “session stuff” (I would need to dig out the details). Because it felt a little “clunky” I avoided threads and found timers worked just fine. With a short running processes a little spinner did a good job of communicating that things were still running and I could start the spinner then do the work in a one shot timer.

With this longer running process, for the most part, I can avoid session properties if I put the logic in a thread EXCEPT that the database is opened in the Session Open event.

So I guess I better dig out the code to connect to the session from a thread.[/quote]
Instead of using a Thread, try a WebThread. If it’s created from an event inside a session, it will remember which one it belongs to.

Hey Greg,

Can you tell us if your implementation idea to show a spinner before the round trip ( <https://xojo.com/issue/47609> ) will be in R2, R3, or R4?

We won’t need to mess with WebThreads and Timers nearly as much with your awesome idea!