CallLater / App.Quit not always working

  1. ‹ Older
  2. 6 weeks ago

    Arthur v

    Apr 16 Testers Netherlands
    Edited 6 weeks ago

    I'm sorry, but I don't really know how to answer that question. The App didn't quit, App.Open finishes after having done a bunch of stuff, including:

    MessageAdd("Starting shutdown timer.")
    timerShutdown = New Timer
    AddHandler timerShutdown.Action, AddressOf timerShutdownAction
    timerShutdown.Period = 5000 // Every 5 seconds
    timerShutdown.Mode = Timer.ModeMultiple

    The code for the timer is in the first post. When the flag {App.shutdownRequest} has been set, it calls the App.Method.

    This always works, except in the scenario I described earlier.

    In both cases {timerShutdown} happily keeps on firing every 5 seconds, but the {QuitApp} is not called if there's a hanging (not properly cleaned up - destructor didn't run) thread / HTTPSocket (HTTP error?) in another part of the App. Therefore I was wondering if this somehow can mess up CallLater.

    As a workaround I've added an extra counter in the timer that wil directly call the method after a couple of cycles. It's not easy to test though as this scenario almost never happens...

  3. James D

    Apr 17 Testers, Xojo Pro Europe (Switzerland)

    You should probably stop accepting connections before going into your close down routine.

  4. Arthur v

    Apr 17 Testers Netherlands

    All connections are closed at that point in time. Except for the one that has not destructed correctly.

    Still, why should it block the CallLater mechanism?

  5. James D

    Apr 17 Testers, Xojo Pro Europe (Switzerland)

    @Arthur v;den Boogaart All connections are closed at that point in time. Except for the one that has not destructed correctly.

    Still, why should it block the CallLater mechanism?

    I don't see anything in your code setting this property to False:

    https://docs.xojo.com/WebApplication.AcceptingConnections

  6. Arthur v

    Apr 17 Testers Netherlands
    Edited 6 weeks ago

    Correct. Should that help or even matter? Does that influence CallLater?

    My app is a web service which does not get incoming connections other then pages received from outgoing REST calls.

    Also, this code works 99% of the time. It's only a problem after the scenario I described earlier.

    It's not that the main thread(s) are busy since everything has been shut down too. The app has plenty of time, which is also witnessed by the precision of the timer going off. Even with every thread running full blast this mechanism works fine as I have sleeps all over the place...

  7. Arthur v

    Apr 17 Testers Netherlands

    @James D I don't see anything in your code setting this property to False:

    https://docs.xojo.com/WebApplication.AcceptingConnections

    I'm wondering how this works though...

    Allows you to Start/Stop a web app's ability to accept connections. Setting this property to False will stop the server(s) and disconnect all active sockets immediately.

    So does it stop accepting new ones and kill all outstanding REST (HTTPSocket) calls? So all threads waiting for a HTTP reply are going to be disrupted?

    If that's the case I won't use it until after these threads have been gracefully exited...

  8. Kevin G

    Apr 17 Xojo Pro Gatesheed, England

    If by web service you mean a console app / service application maybe you could use a different approach.

    Your main thread will have some kind of loop which keeps the process running.

    Rather than your shutdown using CallLater to trigger a method to execute app.Quit, why don't you use a boolean property which indicates if the loop should continue. Your shutdown detection code would flip the property value which would exit the loop and end the process.

  9. Arthur v

    Apr 17 Testers Netherlands

    I appreciate the input, but how would this help me? Right now the app works fine and it's heavily multi-threaded so I don't see how or why I would have to change this. Not sure it would be a better design to begin with, but I'm open for good arguments!

  10. Kevin G

    Apr 17 Xojo Pro Gatesheed, England

    @Arthur v;den Boogaart I appreciate the input, but how would this help me? Right now the app works fine and it's heavily multi-threaded so I don't see how or why I would have to change this. Not sure it would be a better design to begin with, but I'm open for good arguments!

    My approach would mean that you don't need to use CallLater which according to your diagnoses. doesn't appear to be working correctly.

  11. Arthur v

    Apr 17 Testers Netherlands
    Edited 6 weeks ago

    True. But I thought (a loop with only) a sleep for the main thread (in App.Open) was considered to be 'not done'...

    https://forum.xojo.com/34110-sleeping-the-main-thread/p1#p278712

  12. Kevin G

    Apr 17 Xojo Pro Gatesheed, England

    @Arthur v;den Boogaart True. But I thought (a loop with only) a sleep for the main thread (in App.Open) was considered to be 'not done'...

    Oh, it looks like you are doing this using a Desktop project.
    Is there any reason why you aren't using a Console project since your app doesn't have a GUI?

  13. Arthur v

    Apr 17 Testers Netherlands
    Edited 6 weeks ago

    No sorry, it is a console web app...

  14. Kevin G

    Apr 17 Xojo Pro Gatesheed, England

    @Arthur v;den Boogaart No sorry, it is a console web app...

    Sorry, never touched a web app before.

  15. Julian S

    Apr 17 Xojo Pro UK

    Can you replicate this in a small project that you can upload here for us to look over? If you need to block a connection fir the test just try to connect to a random port on localhost.

  16. James D

    Apr 17 Testers, Xojo Pro Europe (Switzerland)
    Edited 6 weeks ago

    @Arthur v;den Boogaart So does it stop accepting new ones and kill all outstanding REST (HTTPSocket) calls? So all threads waiting for a HTTP reply are going to be disrupted?

    Yes it cleanly closed down everything and in my experience it is necessary for a correct clean up.

    @Arthur v;den Boogaart If that's the case I won't use it until after these threads have been gracefully exited...

    But then you need to track the threads and make sure they are correctly closed down, that than giving it a random 20 seconds and hoping for the best.

  17. 5 weeks ago

    Arthur v

    Apr 20 Testers Netherlands

    Thanks for the replies guys! Somehow I didn't get an email from the forum.

    @Julian S - A small project... Dunno about that, will take some time as the App is fairly complex with lots of timers starting threads which spin up threads running (e.g.) XojoScripts in other threads. I'm pretty sure that's related to the issue.

    @James D - I already track the threads because I need to know if they're finished. That gets double checked when the CallLater fires after 20 seconds. *If* it fires.

    For now I'll settle for extra counter I've put in. Also I'm going in to see if I can find a way to catch and destruct the hanging thread (reference?) somehow.

    Just for the record: CallLater is not completely clean though. Maybe it gets queued (?) after (blocked by) the hanging thread or something? No clue how this stuff works internally.

  18. Julian S

    Apr 20 Xojo Pro UK

    Ah I didn't know you're using xojoscript. Are your HTTP Sockets sync or async? Are you starting the sockets in xojoscript? Loops in xojoscript won't yield time on loop boundaries to threads outside xojoscript unless you have app.doevents in the xojoscript.

    The only time I've been able to stop the quit of my test console app so far is when I trap EndException or ThreadEndException and don't re-raise them or block the app with a long running xojoscript. If I block during the xojoscript, no timers fire, even basic timers no matter if they're in the base or in threads so it can't be that if you still have timers firing.

    I really think the little demo will be key here to figure out how you have things in a state where some timers run and others don't.

  19. Arthur v

    Apr 20 Testers Netherlands

    They're async. Thanks for your input! My scripts / loops / threads yield plenty of time as they are all running in parallel non-stop without issues.

    I sometimes (?) get the EndException error too (and re-raise as per manual) so no probs there, but in this case it's a non issue anyway, as the quit method isn't even logging itself - which is the first line of code in there.

    Cheers!

  20. last week

    Arthur v

    May 18 Testers Netherlands
    Edited last week

    Follow up: App.Quit() also doesn't do a thing in this case. A quick reminder...

    As a workaround I've added an extra counter in the timer that wil directly call the method after a couple of cycles. It's not easy to test though as this scenario almost never happens...

    Result: method gets called because the counter works. Here's the brilliant method...

    MessageAdd(CurrentMethodName)
    App.Quit()

    Here's my log...

    010847 (+3) ACT.QuitApp
    010847 (+2) App shutdown: 0.9.0.1144

    010852 (>999) ACT.timerShutdownAction: QuitAppScheduled increased.
    010857 (>999) ACT.timerShutdownAction: QuitAppScheduled increased.
    010902 (>999) ACT.timerShutdownAction: QuitAppScheduled increased.
    010907 (>999) ACT.timerShutdownAction: QuitAppScheduled increased.
    010912 (>999) ACT.timerShutdownAction: QuitAppScheduled increased.
    ...

    The 'App shutdown' part is logged by the 'Stop' event handler. So that piece works. But as you can see the the app happily continues to update my counter as before (which is the only thing left for it to do by the way). Forever. No exceptions. No quitting gracefully.

    So, is there another way to force-quit an app from code? Or should I call some sort of kill script?

  21. 6 days ago

    Arthur v

    May 21 Testers Netherlands
    Edited 6 days ago

    @James D I don't see anything in your code setting this property to False:

    https://docs.xojo.com/WebApplication.AcceptingConnections

    Added this one too. Although it *appears* to close the open sockets (I still need to double check), it doesn't help the shutdown unfortunately.

or Sign Up to reply!