Akin Shonibare

Ravine · ADR 0005 · with 0012, photos by version

5.One cached catalog. Hours and moments are computed on the phone.!

The problem
The map needs every place at once for its pins, Discover needs the issue, onboarding needs the taste wheels. The library is small and curated, tens to a few hundred places, and two things about it change with the clock rather than with the data, whether a place is open now and whether a Toronto Moment is live.
The options
One catalog document with an ETag, kept on the phone and refreshed on launch; conventional resource endpoints for places, curators and lists; or the server computing "open now" so the logic lives in one place.
The move
One document from one endpoint, cached raw on disk with its ETag and refreshed on launch and on returning to the foreground. The server sends each place's weekly hours and each Moment's start and end; the phone decides open, closed and live at render time in Toronto time. The phone keeps the server's bytes as sent, because re-encoding them would rewrite dictionary keys that are display strings.
What we accepted
The whole document moves when one place changes. Hours logic lives in Swift rather than Python, so there are two places it could be wrong. Past a few hundred places the document gets heavy, which is why search stays on the server as the first thing that should scale differently.
When we would revisit
When the catalog response passes about a megabyte, or Ravine opens a second city.

A dozen REST requests before the map draws is the conventional answer, and the wrong one for a guide you open on the street. One request on launch, a 304 on most of them, and the map works offline from the last copy. The part worth defending is where “open now” is computed. A server that answers it produces a cached response that is stale within the hour; a phone that holds the weekly schedule is never stale, because it computes the state when it draws.

The same thinking carries into photos: the catalog names each photo by key and version, the phone keeps every version it has seen, and a photo replaced under the same key reaches every phone on the next refresh without the document growing.

Back to Ravine