Crash Recovery

I've implemented a great feature in my data fields that preserves key CIQ variables following a Garmin device crash/recovery.

Thankfully that is rare event. But it is so frustrating, the 2-3 times a year it happens, when I look down at my Edge device hours into an important ride or race, and it is blank!

Years ago, all the data would have been lost. But now, Garmin does preserve core Activity Info metrics like Timers, Odometer, Calories, etc. So when you realize it died and you tap the power button to restart it (take 2 mins or so!), the core data is still good when you resume the activity. But of course, our CIQ variables are toast.

So I store selected CIQ variables in persistent storage on a regular basis. And upon power up, using a variety of vetting techniques to make sure this is really a restart from a crash and not a new activity... I retrieve the saved data and override the CIQ variables with the good data, and start preserving the data again.

Anyway, it works great. Might not be worth it for most apps or data fields. But on my epic multi-hour rides and races, this is peace of mind, knowing my data fields will still present reliable insights if Garmin decides to reboot on me.

One of my validation checks is that I need to restart within 15 mins of the last "save", or I purge the stored data and ignore it. It isn't always easy to test if the startup is following a crash or is a new activity... so this help prevent corner cases where you start an activity and it applied the previously saved state.

At least on an EDGE you can test it by holding the power button down for about 10 seconds until it crashes mid-activity. And in the simulator, just kill the sim without a stop/discard, then restart it.

Anyway, if you have CIQ apps that could benefit from this kind of logic, it is worth considering implementing a crash recovery module that is reusable across your portfolio.

  • This is a very interesting topic. The biggest problem is that the app doesn't emit any event on hard reboot (onAppStop() method is not being invoked in that case), so the only way to preserve variable values in the storage is doing it on the schedule basis. But a frequent write operation is kinda expensive and device crash or manual hard reboot during the activity is a very rare case, so I decided to sacrifice this recovering feature in my own app in order to not overblow the logic and not to spend much resources on storage write operations.

  • Agree it is rare, but the expense part is debatable. My EDGE 1030 lasts over 13 hours even with this logic. 99% of my activities are less than that. And for my 12-24 hour rides, I keep a small lithium battery in my top tube case with a USB cable to keep it topped off once it hits 25% or so. So, really no issue whatsoever in my case. But the frustration of lost data mid ride is a big deal to me, as my day job includes data analysis and engineering... I dig data LOL