code: func (s *shard) info() *ShardInfo {
  	var rate float64
  	var eta *timestamp.Timestamp
  
  	if runtime := s.Updated.Sub(s.Created); runtime > 0 {
  		rate = float64(s.ProcessedCount) / runtime.Seconds()
  		if s.ExpectedCount != -1 && rate > 0.0001 {
  			secs := float64(s.ExpectedCount) / rate
  			eta = google.NewTimestamp(s.Created.Add(time.Duration(float64(time.Second) * secs)))
  		}
  	}
  
  	return &ShardInfo{
  		Index:             int32(s.Index),
  		State:             s.State,
  		Error:             s.Error,
  		Created:           google.NewTimestamp(s.Created),
  		Updated:           google.NewTimestamp(s.Updated),
  		Eta:               eta, // nil if unknown
  		ProcessedEntities: s.ProcessedCount,
  		TotalEntities:     s.ExpectedCount, // -1 if unknown
  		EntitiesPerSec:    float32(rate),   // 0 if unknown
  	}
  }
docs: // info returns a proto message with information about the shard.