func (spec *workSpec) Meta(withCounts bool) (coordinate.WorkSpecMeta, error) { // If we need counts, we need to run expiry so that the // available/pending counts are rightish if withCounts { _ = withTx(spec, func(tx *sql.Tx) error { return expireAttempts(spec, tx) }) } var meta coordinate.WorkSpecMeta err := withTx(spec, func(tx *sql.Tx) error { var ( query string interval string nextContinuous pq.NullTime ) query = buildSelect([]string{ workSpecPriority, workSpecWeight, workSpecPaused, workSpecContinuous, workSpecCanBeContinuous, workSpecMinMemoryGb, workSpecInterval, workSpecNextContinuous, workSpecMaxRunning, workSpecMaxAttemptsReturned, workSpecNextWorkSpec, }, []string{ workSpecTable, }, []string{ isWorkSpec, // binds $1 }) row := tx.QueryRow(query, spec.id) err := row.Scan( &meta.Priority, &meta.Weight, &meta.Paused, &meta.Continuous, &meta.CanBeContinuous, &meta.MinMemoryGb, &interval, &nextContinuous, &meta.MaxRunning, &meta.MaxAttemptsReturned, &meta.NextWorkSpecName, ) if err != nil { return err } meta.NextContinuous = nullTimeToTime(nextContinuous) meta.Interval, err = sqlToDuration(interval) if err != nil { return err } // Find counts with a second query, if requested if !withCounts { return nil } query = buildSelect([]string{ attemptStatus, "COUNT(*)", }, []string{ workUnitAttemptJoin, }, []string{ inThisWorkSpec, // binds $1 }) query += " GROUP BY " + attemptStatus rows, err := tx.Query(query, spec.id) if err != nil { return err } return scanRows(rows, func() error { var status sql.NullString var count int err := rows.Scan(&status, &count) if err != nil { return err } if !status.Valid { meta.AvailableCount += count } else { switch status.String { case "expired": meta.AvailableCount += count case "retryable": meta.AvailableCount += count case "pending": meta.PendingCount += count } } return nil }) }) return meta, err }