How to restart my app and avoid concurrency

I have an app with child devices and interactions with other device drivers. It’s based around MQTT. I also have an MQTT driver which if it detects a problem with its connection to the broker sends an event back to my app. My app then has the ability to re-initialise the MQTT driver and reconnect. This works fine.

However I really then want to restart my app totally just as if the user had loaded new code and hit ‘done’ . This is because I have to recreate subscriptions and update states on MQTT. But I’m seeing concurrent versions of my app being executed. Several in fact. I thought this was because of forward scheduled runin() methods but it’s not. I unschedule() them all and also unsubscribe() from all events.

So I have been trying to implement this by calling initialize() or updated() on myself. That obviously isn’t the right way. What should I be doing to totally kill myself and restart myself afresh from new ?

Just a couple of thoughts I've had although I'm not sure they'll fix the issue, I'd really like to know how to implement the last question in the above post

The reconnects to MQTT should probably be handled totally within the MQTT driver without eventing back to the main app and then calling back to the MQTT driver initialize command.

Maybe things like the topic subscriptions should be handled in child applications that have no event handlers. I feel my main issue with the big single app is that it's being 'interrupted' at unpredictable times by the broker when it encounters connection issues and that means it's starting another duplicate app version of itself and then returning into the original one too.

Following on from this.. I'm making good progress but still battling concurrency so a few questions.

  1. My App has a lot of sequential steps when starting up, it could take maybe 10 minutes or so to complete initialize(). I assume if I just execute a return within initialize() it would then be stopped and sowould then only execute any forward scheduled methods or react to events.

  2. So assuming I'm halfway through initialize() and my MQTT broker connection is then lost. I already have an event generated back into my app ... but to start the app again from scratch i.e. stop the existing initialize() mid flow I would have to test for a condition repeatedly and frequently in initialize() and execute a return if true ?

if (MQTTlost) return

  1. Is there any way I could tell if two or more instances of my app are running , and if so kill the previous ones automatically ? I'm assuming they would all be within their initialize() method.

  2. If initialize() has completed on several instances on my app then only events (or scheduled methods) will kick it back into action... so will those events only be passed to one instance of the app or might several (if they exist) react to the events. The events would come from device state changes that I've subscribed to or from incoming messages on MQTT - my child driver. When trying to restart cleanly I do unsubscribe() and unschedule() everything.

Really I just want to kill my app totally (and any instances) and restart it from scratch. I now realise're-executing with 'Done' does not achieve that.

The complication is that the MQTT disconnects can happy quite frequently with a bad MQTT connection during those first 10 minutes during startup (initialize) so that's spawning multiple instances of my app.

I have found I can use runIn() to avoid creating restarts that occur in quick succession - but setting an atomicState var and then using it as a test to avoid a second restart doesn't work..

I am surprised how easy it is to create multiple instances of one app .. and wonder if other apps are unknowingly doing this too.. perhaps contributing to a progressive slowdown of the hub.. that a restart fixes.. as a few are reporting. I see them because of duplicate logging messages.

I am not going to be be much help but boosting this so more educated eys will see it.

1 Like

Thanks Helene and Bob, it was lonely here :sleepy:

Just last night I implemented what I thought was a bit of a kludge to eradicate this. In talking with HE today (many thanks) they suggested my workaround as a viable solution so I'm happier now.

When I have it proven in a few days I'll post an update here that explains a little more about the app life cycle and why duplicate instances can happen, causing concurrency which creates hub slowdowns which can rapidly escalate until a reboot, and then how you can terminate these concurrent apps so this doesn't happen.

Nobody may be interested now but at least it'll pop up in a search in the future.

1 Like