Example #1
0
// GetWorkUnits retrieves the keys and data dictionaries for some number
// of work units.  If options contains "work_unit_keys", those specific
// work units are retrieved; otherwise the work units are based on
// which of GetWorkUnitsOptions are present.
//
// On success, the return value is a slice of cborrpc.PythonTuple
// objects where each contains the work unit key as a byte slice and
// the data dictionary.
func (jobs *JobServer) GetWorkUnits(workSpecName string, options map[string]interface{}) ([]interface{}, string, error) {
	var workUnits map[string]coordinate.WorkUnit
	gwuOptions := GetWorkUnitsOptions{
		Limit: 1000,
	}

	spec, err := jobs.Namespace.WorkSpec(workSpecName)
	var decoder *mapstructure.Decoder
	if err == nil {
		config := mapstructure.DecoderConfig{
			DecodeHook: mapstructure.ComposeDecodeHookFunc(gwuStateHook, cborrpc.DecodeBytesAsString),
			Result:     &gwuOptions,
		}
		decoder, err = mapstructure.NewDecoder(&config)
	}
	if err == nil {
		err = decoder.Decode(options)
	}
	if err == nil {
		query := coordinate.WorkUnitQuery{
			Names: gwuOptions.WorkUnitKeys,
		}
		if gwuOptions.WorkUnitKeys == nil {
			query.PreviousName = gwuOptions.Start
			query.Limit = gwuOptions.Limit
		}
		if gwuOptions.WorkUnitKeys == nil && gwuOptions.State != nil {
			query.Statuses = make([]coordinate.WorkUnitStatus, len(gwuOptions.State))
			for i, state := range gwuOptions.State {
				query.Statuses[i], err = translateWorkUnitStatus(state)
				if err != nil {
					break
				}
			}
		}
		if err == nil {
			workUnits, err = spec.WorkUnits(query)
		}
	}
	if err != nil {
		return nil, "", err
	}
	// The marshalled result is a list of pairs of (key, data).
	var result []interface{}
	for name, unit := range workUnits {
		var data map[string]interface{}
		attempt, err := unit.ActiveAttempt()
		if err == nil && attempt != nil {
			data, err = attempt.Data()
		}
		if err == nil && data == nil {
			data, err = unit.Data()
		}
		if err != nil {
			return nil, "", err
		}
		tuple := cborrpc.PythonTuple{Items: []interface{}{[]byte(name), data}}
		result = append(result, tuple)
	}
	return result, "", nil
}