Serve a JSON array of run names, ordered by run started time.

    Sort order is by started time (aka first event time) with empty times sorted
    last, and then ties are broken by sorting on the run name.

def _serve_runs(self, request):
    """Serve a JSON array of run names, ordered by run started time.

    Sort order is by started time (aka first event time) with empty times sorted
    last, and then ties are broken by sorting on the run name.
    """
    if self._db_connection_provider:
      db = self._db_connection_provider()
      cursor = db.execute('''
        SELECT
          run_name,
          started_time IS NULL as started_time_nulls_last,
          started_time
        FROM Runs
        ORDER BY started_time_nulls_last, started_time, run_name
      ''')
      run_names = [row[0] for row in cursor]
    else:
      # Python's list.sort is stable, so to order by started time and
      # then by name, we can just do the sorts in the reverse order.
      run_names = sorted(self._multiplexer.Runs())
      def get_first_event_timestamp(run_name):
        try:
          return self._multiplexer.FirstEventTimestamp(run_name)
        except ValueError as e:
          logger.warn(
              'Unable to get first event timestamp for run %s: %s', run_name, e)
          # Put runs without a timestamp at the end.
          return float('inf')
      run_names.sort(key=get_first_event_timestamp)
    return http_util.Respond(request, run_names, 'application/json')