<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state

import (
	"github.com/juju/errors"
	"github.com/juju/loggo"
	"github.com/juju/names"

	"github.com/juju/juju/workload"
	"github.com/juju/juju/workload/persistence"
)

var logger = loggo.GetLogger("juju.workload.state")

// TODO(ericsnow) Add names.WorkloadTag and use it here?

// TODO(ericsnow) We need a worker to clean up dying workloads.

// The persistence methods needed for workloads in state.
type workloadsPersistence interface {
	Track(info workload.Info) (bool, error)
	// SetStatus updates the status for a payload.
	SetStatus(docID, status string) (bool, error)
	List(ids ...string) ([]workload.Info, []string, error)
	ListAll() ([]workload.Info, error)
	Untrack(id string) (bool, error)
}

// UnitWorkloads provides the functionality related to a unit's
// workloads, as needed by state.
type UnitWorkloads struct {
	// Persist is the persistence layer that will be used.
	Persist workloadsPersistence
	// Unit identifies the unit associated with the workloads.
	Unit names.UnitTag
}

// NewUnitWorkloads builds a UnitWorkloads for a unit.
func NewUnitWorkloads(st persistence.PersistenceBase, unit names.UnitTag) *UnitWorkloads {
	persist := persistence.NewPersistence(st, unit)
	return &UnitWorkloads{
		Persist: persist,
		Unit:    unit,
	}
}

// Track inserts the provided workload info in state.
func (ps UnitWorkloads) Track(info workload.Info) error {
	logger.Tracef("tracking %#v", info)
	if err := info.Validate(); err != nil {
		return errors.NewNotValid(err, "bad workload info")
	}

	ok, err := ps.Persist.Track(info)
	if err != nil {
		return errors.Trace(err)
	}
	if !ok {
		return errors.NotValidf("workload %s (already in state)", info.ID())
	}

	return nil
}

// SetStatus updates the raw status for the identified workload to the
// provided value.
func (ps UnitWorkloads) SetStatus(docID, status string) error {
	logger.Tracef("setting payload status for %q/%q to %q", docID, status)

	if err := workload.ValidateState(status); err != nil {
		return errors.Trace(err)
	}

	found, err := ps.Persist.SetStatus(docID, status)
	if err != nil {
		return errors.Trace(err)
	}
	if !found {
		return errors.NotFoundf(docID)
	}
	return nil
}

func validateStatus(status string) error {
	switch status {
	case workload.StateStarting,
		workload.StateRunning,
		workload.StateStopping,
		workload.StateStopped:
		return nil
	}
	return errors.Errorf("invalid status, must be one of the following: starting, running, stopping, stopped")
}<commit_msg>fixing trace output<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state

import (
	"github.com/juju/errors"
	"github.com/juju/loggo"
	"github.com/juju/names"

	"github.com/juju/juju/workload"
	"github.com/juju/juju/workload/persistence"
)

var logger = loggo.GetLogger("juju.workload.state")

// TODO(ericsnow) Add names.WorkloadTag and use it here?

// TODO(ericsnow) We need a worker to clean up dying workloads.

// The persistence methods needed for workloads in state.
type workloadsPersistence interface {
	Track(info workload.Info) (bool, error)
	// SetStatus updates the status for a payload.
	SetStatus(docID, status string) (bool, error)
	List(ids ...string) ([]workload.Info, []string, error)
	ListAll() ([]workload.Info, error)
	Untrack(id string) (bool, error)
}

// UnitWorkloads provides the functionality related to a unit's
// workloads, as needed by state.
type UnitWorkloads struct {
	// Persist is the persistence layer that will be used.
	Persist workloadsPersistence
	// Unit identifies the unit associated with the workloads.
	Unit names.UnitTag
}

// NewUnitWorkloads builds a UnitWorkloads for a unit.
func NewUnitWorkloads(st persistence.PersistenceBase, unit names.UnitTag) *UnitWorkloads {
	persist := persistence.NewPersistence(st, unit)
	return &UnitWorkloads{
		Persist: persist,
		Unit:    unit,
	}
}

// Track inserts the provided workload info in state.
func (ps UnitWorkloads) Track(info workload.Info) error {
	logger.Tracef("tracking %#v", info)
	if err := info.Validate(); err != nil {
		return errors.NewNotValid(err, "bad workload info")
	}

	ok, err := ps.Persist.Track(info)
	if err != nil {
		return errors.Trace(err)
	}
	if !ok {
		return errors.NotValidf("workload %s (already in state)", info.ID())
	}

	return nil
}

// SetStatus updates the raw status for the identified workload to the
// provided value.
func (ps UnitWorkloads) SetStatus(docID, status string) error {
	logger.Tracef("setting payload status for %q to %q", docID, status)

	if err := workload.ValidateState(status); err != nil {
		return errors.Trace(err)
	}

	found, err := ps.Persist.SetStatus(docID, status)
	if err != nil {
		return errors.Trace(err)
	}
	if !found {
		return errors.NotFoundf(docID)
	}
	return nil
}

func validateStatus(status string) error {
	switch status {
	case workload.StateStarting,
		workload.StateRunning,
		workload.StateStopping,
		workload.StateStopped:
		return nil
	}
	return errors.Errorf("invalid status, must be one of the following: starting, running, stopping, stopped")
}
{'fraction_non_alphanumeric': 0.1113465613561934, 'fraction_numerical': 0.0019264110961279136, 'mean_word_length': 4.287169042769857, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1655449', 'n_tokens_mistral': 1752, 'n_tokens_neox': 1680, 'n_words': 528}