func (ns *namespace) SetWorkSpec(data map[string]interface{}) (coordinate.WorkSpec, error) { name, meta, err := coordinate.ExtractWorkSpecMeta(data) if err != nil { return nil, err } spec := workSpec{ namespace: ns, name: name, } err = withTx(ns, func(tx *sql.Tx) error { row := tx.QueryRow("SELECT work_spec.id FROM work_spec WHERE namespace_id=$1 AND name=$2", ns.id, name) err = row.Scan(&spec.id) if err == nil { err = spec.setData(tx, data, meta) } else if err == sql.ErrNoRows { var dataBytes []byte dataBytes, err = mapToBytes(data) if err != nil { return err } interval := durationToSQL(meta.Interval) nextContinuous := timeToNullTime(meta.NextContinuous) row = tx.QueryRow("INSERT INTO work_spec(namespace_id, name, data, priority, weight, paused, continuous, can_be_continuous, min_memory_gb, interval, next_continuous, max_running, max_attempts_returned, next_work_spec_name, next_work_spec_preempts) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING id", ns.id, name, dataBytes, meta.Priority, meta.Weight, meta.Paused, meta.Continuous, meta.CanBeContinuous, meta.MinMemoryGb, interval, nextContinuous, meta.MaxRunning, meta.MaxAttemptsReturned, meta.NextWorkSpecName, false) err = row.Scan(&spec.id) } return err }) if err != nil { return nil, err } return &spec, nil }
func (spec *workSpec) SetData(data map[string]interface{}) error { name, meta, err := coordinate.ExtractWorkSpecMeta(data) if err != nil { return err } if name != spec.name { return coordinate.ErrChangedName } return withTx(spec, func(tx *sql.Tx) error { return spec.setData(tx, data, meta) }) }
// setData is an internal version of SetData() with the same constraints, // guarantees, and checking. It assumes the global lock. func (spec *workSpec) setData(data map[string]interface{}) error { name, meta, err := coordinate.ExtractWorkSpecMeta(data) if err == nil { if name != spec.name { err = coordinate.ErrChangedName } } if err == nil { spec.data = data spec.meta = meta } return err }