Weathrman 4.0: By Popular Demand

I’ve got a shiny new Xoom, and now you have a shiny new Weathrman client.

The biggest changes here are all around two user stories I’ve heard more than anything else:

  • I installed the app, but it doesn’t do anything and I can’t find it.
  • I need more control over how the application uses data on my device.

To address the former, we’ve got a launcher, dialogs on preview, and an embedded usage guide to help the user get the live wallpaper selected on their devices.

To address the latter, we’ve now got a pretty good story on data controls:

  • We now obey background data settings. If you turn off background data support, you can still refresh the wallpaper manually, but all automated, non-interactive network activity is stopped.
  • Support for disabling use of 2G/3G and WiMAX networks, for those who want wifi-only.
  • Control over walllpaper refresh rate.

Now that we’re allowed a lot fewer search terms, we’re doing a lot more fan-out of requests to flickr; a single user can now result in about 5,000 flickr requests, fired off in under 30 seconds. The pressure is on to find better search terms and filter terms, and so our next steps will be to take advantage of the prediction API and start using machine learning to make better decisions.

Sick days, Weathrman, and you

So I’m home sick today, and going through the laundry list of things I haven’t gotten around to recently.

Weathrman is on that list.

I’ve pushed a new version of the server that performs searches on behalf of app users up.  This is designed to do two things:  reduce the cost of running the service, and improve the search quality.

In order to reduce the cost, I’m going to do the obvious thing:  I’m going to produce fewer searches.  Specifically, that means:

  • Instead of asking for a 3-hour window, we’re asking for a 4-hour window around ‘now’.
  • Increase the search window from 3 months to 4 months (2 in either direction)
  • Fetch 4 pages of results instead of 5.
  • Reduce the minimum number of results needed at any search level from 5 to 3.
  • Remove street-level searching (level 16) - it too rarely has results, and just creates latency.

 This means our worst case goes from being 7 tiers of 5 parallel searches to being 6 tiers of 4 parallel searches.  It also means the average case, which cost 1 tier of 5 searches before we were likely to find any results, will now get faster, and I won’t be paying for that wasted time.

The downside is that I’m only fetching four pages of results; searches cover the entire four-month window, and it’s possible that none of the first four pages will have photos taken within the required time-of-day range; if that happens, we skip up a level.  Dropping one of the pages of search results makes that more likely, and it’s probably not completely mitigated by the widening of the 3-hour window to 4.  The net effect is that searches may feel… a little less local.

Hopefully, these changes mean I’ll be able to continue supporting this service for longer, and more cheaply.  Going back to the days when the client was responsible for performing all these searches just isn’t going to happen - it’s just too convenient to be able to run the searches from the server, and much more reliable.  It does mean that I’m bearing the cost of a free app - but as long as I can keep the costs down, I don’t mind.

Weathrman 3.5.1: The Best Intentions

I’ve taken some time to do some internal cleanup; I’ve learned a great deal about Android’s programming model from building this and other projects, and it’s time to go back and re-apply some of that knowledge.

As such, I’ve restructured the bulk of execution in IntentService implementations, which has simplified a lot of the code; notification handling and update processing are now handled by dedicated services, rather than burying the whole processing chain in an AsyncTask.

We’ve lost a few things I’d like to have kept along the way, on the inside, but the code is cleaner and faster for it.

I’ve also done something I thought I’d never see myself do:  I’ve de-guiced the app.

Done well, I’m sure Guice is a good fit; but it’s a very small app, and moving to IntentService instances has basically meant that I’ve now got three independent application-parts that communicate by sending intents to one another.  What’s left isn’t worth Guicing.

What’s funny, and somewhat unfortunate, is that by coming to this with my server hat on, I missed the fact that Android applications don’t need to be built as the monolith binaries that Guice is designed to help break apart, and some of the tools at your disposal on android are designed to ensure that not only do you not need to allocate those objects, you can avoid most of the processing time you would have spent even thinking about those elements of the object graph - binding processing just isn’t free, and on mobile devices you might not see the cost, but you can feel it, almost imperceptibly.

So 3.5.1 is out; it’s got fixes for the cache growth problems, reaffirms my commitment to 2.1-based devices, and provides a much needed speed boost in both startup performance and, due to some more tweaking on my part, on the speed of image retrieval in many cases.

I’ve also tweaked the negative keywords associated with daytime searches on the server side; hopefully you’ll see improved search quality.

And for a short time, it’s free - I’m looking to get an idea of how active users correspond with server load, and giving away a free app is a cheap way of load testing.  :)

Of Clouds and Silver Linings

I’ve updated the AppEngine app that weathrman uses to perform its searches to a later version of the SDK; hopefully people will either see no change, or see improved response times; I’ll be monitoring the service over the next few days to ensure that all is well, and that error rates stay roughly where they were (or drop).

Fingers crossed.