Пример #1
0
// ControlWorkSpec makes changes to a work spec that are not directly
// reflected in the work spec definition.  This allows work specs to
// be paused or to stop generating new continuous jobs.
// ControlWorkSpecOptions has a complete listing of what can be done.
func (jobs *JobServer) ControlWorkSpec(workSpecName string, options map[string]interface{}) (bool, string, error) {
	var (
		cwsOptions ControlWorkSpecOptions
		decoder    *mapstructure.Decoder
		err        error
		metadata   mapstructure.Metadata
		workSpec   coordinate.WorkSpec
		wsMeta     coordinate.WorkSpecMeta
	)

	workSpec, err = jobs.Namespace.WorkSpec(workSpecName)
	if err == nil {
		// We care a lot about "false" vs. not present for
		// these things.  Manually create the decoder.
		config := mapstructure.DecoderConfig{
			Result:   &cwsOptions,
			Metadata: &metadata,
		}
		decoder, err = mapstructure.NewDecoder(&config)
	}
	if err == nil {
		err = decoder.Decode(options)
	}

	// Get the existing metadata, then change it based on what
	// we got provided
	if err == nil {
		wsMeta, err = workSpec.Meta(false)
	}
	if err == nil {
		for _, key := range metadata.Keys {
			switch key {
			case "Continuous":
				wsMeta.Continuous = cwsOptions.Continuous
			case "Status":
				wsMeta.Paused = cwsOptions.Status == Paused
			case "Weight":
				wsMeta.Weight = cwsOptions.Weight
			case "Interval":
				wsMeta.Interval = time.Duration(cwsOptions.Interval) * time.Second
			case "MaxRunning":
				wsMeta.MaxRunning = cwsOptions.MaxRunning
			}
		}
	}
	if err == nil {
		err = workSpec.SetMeta(wsMeta)
	}
	return err == nil, "", err
}
Пример #2
0
// TestMetaContinuous specifically checks that you cannot enable the
// "continuous" flag on non-continuous work specs.
func TestMetaContinuous(t *testing.T) {
	var (
		err       error
		namespace coordinate.Namespace
		spec      coordinate.WorkSpec
		meta      coordinate.WorkSpecMeta
	)

	namespace, err = Coordinate.Namespace("TestMetaContinuous")
	if !assert.NoError(t, err) {
		return
	}
	defer namespace.Destroy()

	spec, err = namespace.SetWorkSpec(map[string]interface{}{
		"name":   "spec",
		"min_gb": 1,
	})
	if !assert.NoError(t, err) {
		return
	}

	meta, err = spec.Meta(false)
	if assert.NoError(t, err) {
		assert.False(t, meta.Continuous)
		assert.False(t, meta.CanBeContinuous)
	}

	meta.Continuous = true
	err = spec.SetMeta(meta)
	assert.NoError(t, err)

	meta, err = spec.Meta(false)
	if assert.NoError(t, err) {
		// Cannot set the "continuous" flag
		assert.False(t, meta.Continuous)
		assert.False(t, meta.CanBeContinuous)
	}
}
Пример #3
0
// GetWorkSpecMeta returns a set of control options for a given work
// spec.  The returned map has the full set of keys that
// ControlWorkSpec() will accept.
func (jobs *JobServer) GetWorkSpecMeta(workSpecName string) (result map[string]interface{}, _ string, err error) {
	var (
		workSpec coordinate.WorkSpec
		meta     coordinate.WorkSpecMeta
	)

	workSpec, err = jobs.Namespace.WorkSpec(workSpecName)
	if err == nil {
		meta, err = workSpec.Meta(false)
	}
	if err == nil {
		result = make(map[string]interface{})
		if meta.Paused {
			result["status"] = Paused
		} else {
			result["status"] = Runnable
		}
		result["continuous"] = meta.Continuous
		result["interval"] = meta.Interval.Seconds()
		result["max_running"] = meta.MaxRunning
		result["weight"] = meta.Weight
	}
	return
}
Пример #4
0
// TestSetMeta tests the basic SetMeta() call and a couple of its
// documented oddities.
func TestSetMeta(t *testing.T) {
	var (
		err       error
		namespace coordinate.Namespace
		spec      coordinate.WorkSpec
		meta      coordinate.WorkSpecMeta
	)

	namespace, err = Coordinate.Namespace("TestSetMeta")
	if !assert.NoError(t, err) {
		return
	}
	defer namespace.Destroy()

	spec, err = namespace.SetWorkSpec(map[string]interface{}{
		"name":       "spec",
		"min_gb":     1,
		"continuous": true,
	})
	if !assert.NoError(t, err) {
		return
	}

	meta, err = spec.Meta(false)
	if assert.NoError(t, err) {
		assert.Equal(t, 0, meta.Priority)
		assert.Equal(t, 20, meta.Weight)
		assert.False(t, meta.Paused)
		assert.True(t, meta.Continuous)
		assert.True(t, meta.CanBeContinuous)
		assert.Zero(t, meta.Interval)
		assert.WithinDuration(t, time.Time{}, meta.NextContinuous, 1*time.Microsecond)
		assert.Equal(t, 0, meta.MaxRunning)
		assert.Equal(t, 0, meta.MaxAttemptsReturned)
		assert.Equal(t, "", meta.NextWorkSpecName)
		assert.Equal(t, 0, meta.AvailableCount)
		assert.Equal(t, 0, meta.PendingCount)
		assert.Equal(t, "", meta.Runtime)
	}

	err = spec.SetMeta(coordinate.WorkSpecMeta{
		Priority:            10,
		Weight:              100,
		Paused:              true,
		Continuous:          false,
		CanBeContinuous:     false,
		Interval:            time.Duration(60) * time.Second,
		MaxRunning:          10,
		MaxAttemptsReturned: 1,
		NextWorkSpecName:    "then",
		AvailableCount:      100,
		PendingCount:        50,
		Runtime:             "go",
	})
	assert.NoError(t, err)

	meta, err = spec.Meta(false)
	if assert.NoError(t, err) {
		assert.Equal(t, 10, meta.Priority)
		assert.Equal(t, 100, meta.Weight)
		assert.True(t, meta.Paused)
		assert.False(t, meta.Continuous)
		// Cannot clear "can be continuous" flag
		assert.True(t, meta.CanBeContinuous)
		assert.Equal(t, 60*time.Second, meta.Interval)
		assert.WithinDuration(t, time.Time{}, meta.NextContinuous, 1*time.Microsecond)
		assert.Equal(t, 10, meta.MaxRunning)
		assert.Equal(t, 1, meta.MaxAttemptsReturned)
		// Cannot change following work spec
		assert.Equal(t, "", meta.NextWorkSpecName)
		// Cannot set the counts
		assert.Equal(t, 0, meta.AvailableCount)
		assert.Equal(t, 0, meta.PendingCount)
		// Cannot change the language runtime
		assert.Equal(t, "", meta.Runtime)
	}
}