Author Archives: frogsparks

MyTrails 2: transparent system UI

In a continued effort to make the map the most important part of MyTrails, I’ve started experimenting with a transparent action bar, and on Kitkat a transparent status and navigation bar.

I need to tweak it a bit more, and refresh the HUD, but so far I like it a lot!

With physical buttons

With a navigation bar (no physical buttons)

With a navigation bar (no physical buttons)

With physical buttons

MyTrails 2: Navigation drawer or drop-down navigation?

I’ve been experimenting with the navigation drawer that many apps are implementing, and I wanted to get some feedback.

Which do you prefer:

Drop-down navigation Navigation drawer
Drop-down navigation Navigation drawer

Pros and cons:

  • the drawer allows me to add more than just navigation: help icons, etc.
  • the drawer animation doesn’t work over OpenGL views, so I’ll have to disable the animations; it’ll be a bit abrupt
  • the drop-down navigation is more discoverable to users who haven’t been exposed to the drawer much (or who have only used it with swipe gestures)

Please use the comments to voice your opinion and suggestions.

Update: I’ve released an update to the alpha/preview with the new navigation, and the ability to toggle between the drop-down and nav-drawer style): use the toggle nav mode hidden option to alternate between the two. I’ve also added icons (5 icons are as much work to me as some features…).

Outage

maps.frogsparks.com is not accessible at the moment due to an outage at my hosting company. They’re offering no ETA but they’re usually quick.

The hosting company resolved the issue (a malfunctioning router) and the server is back. Thank you for your patience!

Update: a different issue is now affecting access to maps.frogsparks.com (and to this server as well), but there is not much I can do to speed up resolution of this one: I recently changed registrars for my domain, and the registrar I left stopped serving my DNS before the DNS TTL expired, so some DNS servers still have old information in their cache. This should resolve itself within a few hours. Im very sorry about this further outage.

One way you can resolve it for yourself is to start using a global DNS such as OpenDNS, which has already updated their cache.

Update 2: when it rains, it pours: I have just worked around an issue on the IGN (France) map server, which caused MyTrails to display checkered tiles instead of the map.

App of the Day promo: what happened?

On Tuesday, MyTrails was featured as the App of the Day by AppTurbo, in a promotion that offered MyTrails Pro for free for a year.

Summary

The promotion was a great success, with over 120.000 new users trying out MyTrails, but it was marred by a 30-minute technical glitch that caused the promo to not automatically activate for thousands of users, some of whom reacted politely and patiently, and others not so much…

In the spirit of full disclosure, here is my analysis of what went wrong and how I attempted to rectify the situation. I hope this will make it clear that the promo was not an attempt to trick users with a bait-and-switch tactic, and that AppTurbo have had no responsibility in the issue (I don’t know what AppTurbo’s business model is, but I didn’t pay anything for the promo). The mistake was all mine.

Preparation

Promos like this are not spur of the moment things: I had had about a month to prepare for it. AppTurbo had warned me to expect high traffic, and I had tuned and tested the authorization server used by MyTrails, to make sure it could handle a sustained load of 120 requests per second with peaks of 1000 rps.

Technical details:
The server normally records a request log so I can replay transactions in the event they fail, and I disabled that. I also normally load up all the logs into an elasticsearch instance with logstash (also disabled). I use LogEntries for some lighter logging, and I didn’t disable that.
I switched the database connection pooling implementation from tomcat jdbc to BoneCP due to its reputation for high reliability and low overhead. This turned out to be a big mistake (not BoneCP’s fault)…
I also switched the request that activates the promotion from https to http to decrease the load on the server (and only because it carries no personal information, just a randomly-generated and MyTrails-specific UUID). Other requests continue to use https.

I had also made changes in MyTrails to reduce the number of requests it made to minimize the strain on the server (disabled the version update check among other things), and added an error message in the event the server was overwhelmed, with an automatic retry mechanism.

Genymotion pour usage personnel - Nexus 7 - 4.3 - API 18 - 1280x800 (1280x800, 213dpi) - 192.168.56.101 2014-03-13 10-25-29 2014-03-13 10-25-33

I also added a tongue-in-cheek message for users who didn’t activate the offer during the validity period, letting them know they could contact me for assistance.

Genymotion pour usage personnel - Nexus 7 - 4.3 - API 18 - 1280x800 (1280x800, 213dpi) - 192.168.56.101 2014-03-13 10-24-31 2014-03-13 10-24-46

On the day

Everything started great, with a short spike just after 8am, presumably when AppTurbo rolled over from their previous promo to MyTrails, then a ramp-up toward 11am.

catalina.out | Logentries 2014-03-13 09-43-58 2014-03-13 09-44-09

An approximation of the number of requests per second throughout the day

The server load remained very low (it’s a nice server) throughout the day despite processing close to 100 requests per second for sustained periods. Interestingly, the server that hosts this blog (a smaller, shared server) registered a higher CPU load than the auth server.

logentries_load

Server loads for the same period

And then I got an email from a user who was getting an error trying to create an account (not a required step, but one I advised users to take, so they could use MyTrails on multiple devices).

A quick investigation uncovered the error below: my email provider was no longer accepting the new account confirmation emails the server was attempting to send.

The first connection refused from my email provider (Google)

The first connection refused from my email provider (Google)

Technical details:
Normally, the server handled email sending errors gracefully, because in most cases the email confirmation is not necessary, but two things happened:
The javax.mail package broke its contract by throwing an exception that is not declared by the method I was calling, so I hadn’t taken that exception into account and the server was sending back the wrong type of error message, confusing MyTrails
For users connecting MyTrails to their Google account (the majority) rather than creating a FrogSparks account, a confirmation email is not necessary, and in retrospect should not have been sent, which would probably avoided triggering the problem in the first place

This error was not preventing the promo activation, but it was making it more difficult for users to follow instructions and associate MyTrails to their Google accounts (or create a separate FrogSparks account, for users leery of using their Google account everywhere), so I rushed to fix the issue.

The timeline of the failure

The timeline of the failure

It was a simple fix, and only took about 7 minutes to implement (11:04 to 11:11 approximately), during which I stopped the server, and MyTrails displayed the try again later error message to users trying to activate the promo.

Unfortunately, when I deployed the fix, the tools that I use introduced a glitch that caused the server to fail to connect to the database; this caused the server to send an unforeseen error back to MyTrails, which responded by displaying the promo expired message, and stopping the automatic retry mechanism for the promo activation (my biggest mistake was to not have made MyTrails react more specifically to the error messages it was receiving).

Technical details:
The issue was caused by a conflict between BoneCP, which depends on a recent version of the Google Guava library, and the Google OAuth package, which contains an antiquated version of the same (then called Google Collections). For some reason, the google-collections-1.0.jar was reintroduced into the build by my IDE and overrode the more recent Guava, causing BoneCP to fail.

This more critical error took longer to diagnose and fix, and by the time it was repaired at 11:33, thousands of people who had tried to activate the promo were shown an incorrect error alert and left with the option of sending email to my support mailbox or leave angry 1-star reviews on the Play Store.

Aftermath

I tried to quickly provide a work-around for activating the promo despite the problem (luckily such a work-around existed and was already documented, albeit initially targeted at people who were not eligible to the promo), answering support emails and answering Play Store reviews.

I even made a short (and fairly low-quality) screengrab movie to help users type in the correct code in the right location and posted updated instructions at 12:30, and started directing affected (and very disaffected) users to the page.

Needless to say, a subset of people who are used to getting free apps on a daily basis have little patience for anything that stands between them and instant gratification, so while most users who got the solution were able to correctly activate the promo, many didn’t try again and left angry 1-star reviews and/or uninstalled the app.

This user was able to fix the problem after an initially scathing review

This user was able to fix the problem (using a different method) after an initially scathing review

This one probably won't even try

This one probably won’t even try

That night I also deployed an updated version to help restore the auto-retry mechanism for users who hadn’t used the work-around. Probably too late for many, who had already uninstalled or who will not launch the app again after the update.

A successful promo?

Despite the issue and disappointment at having let people down (engineers don’t like to be the source of failure), initial results point at a very successful promo:

  • the Play Store reports a bit less than 120k installs (but it is updated with a delay and the cut-off times are a bit opaque, so I’ll have to wait a few days to find out exactly)
  • about 15k users did uninstall MyTrails on the same day, whether because they disliked the app, as a result of the activation problem, or because it’s their SOP (grab the promo, uninstall the app so it doesn’t crowd the device, reinstall it if needed later)
  • a bit over 90k users were able to activate the promo, which leaves about 15k unactivated users, assuming the 15k uninstalls were not activated (I have extended the validity period to give more time to these users)
  • the flood of 1-star reviews hurt MyTrails’ average rating in the countries where the promo was offered (AppTurbo do not operate in all countries, so the promo was country-specific; in particular I am not able to use App of the Day in France)
Italy and Spain, where MyTrails previously had higher reviews than in other countries (free official topo maps), dipped sharply

Italy and Spain, where MyTrails previously had higher reviews than in other countries (free official topo maps), dipped sharply

To large developers (or very successful indies), 100.000 downloads is small potatoes. To MyTrails, it’s a huge boost, and I hope the promo will trigger some spill-over in countries where I sell topo maps (my main source of revenue). It’s too early to tell, and since the free version of MyTrails carries no advertising, any financial effect will only be felt in the long term anyway.

I’m very glad to have had the opportunity to work with AppTurbo on this, and I’ve learned a valuable lesson. Now I need a similar promo for France!

1.4.5

  • My sincere apologies to users who had trouble activating the App of the Day promotion; if you haven’t yet activated the promotion, this version should do it for you automatically
  • You can now follow us on Facebook
  • Fixed reported errors

MyTrails Pro free with App of the Day

App of the Day

Tomorrow (March 11th) MyTrails will be featured in the App of the Day promo, so installing MyTrails with the App of the Day application will activate the Pro version for free for one year.

This will work only for new users, so what about faithful existing users, or users in countries that App of the Day does not cover (such as France)? You can use the following trick:

Use the simulate referrer appturbo hidden option to activate the promo (make sure to enter that string exactly: no extra spaces, no capitalization, etc.)

You have to do this before the promo ends (late on March 14th).

Update: due to an unforeseen server error, many users were unable to get MyTrails to validate the promo automatically. Here is a step-by-step video to help you activate the promo manually. My sincere apologies for the trouble!

Another update: due to the load, my email provider is no longer accepting activation emails I am trying to send when a new FrogSparks account is created. You can still associate MyTrails with your Google account, but now create a FrogSparks account. Please try again in a day or so.

Resolution: I have updated MyTrails in the Play Store to automatically retry to activate the promotion when it is restarted, please update and try again. I have also extended the promo until the 14th to give everyone a chance to recover. Thank you for your patience.

You can also read a detailed explanation of what happened.

Update 15 March: I have extended the activation period to March 25; if you recently tried to activate and were refused, please try again.

1.4.3

  • Improved track drawing
  • Fixed total recording time calculation
  • Improved time and distance colorizations (dashed): when the recording quality is insufficient or map zoomed out too far, the colorization is disabled
  • Support creation of extremely large offline maps (‘toggle bigger mgm’ hidden option)
  • Easier waypoint selection: tap the point or body