<commit_before>package coprhd

import (
	"errors"
	"fmt"
	"time"
)

const (
	GetTaskUriTpl = "vdc/tasks/%s.json"

	TaskPollDelay              = time.Millisecond * 250
	TaskStatePending TaskState = "pending"
	TaskStateError   TaskState = "error"
	TaskStateReady   TaskState = "ready"
)

var (
	ErrTaskWaitTimeout = errors.New("WaitDone timeout")
)

type (
	TaskService struct {
		*Client
	}

	Task struct {
		Name        string        `json:"name"`
		Id          string        `json:"id"`
		State       TaskState     `json:"state"`
		Message     string        `json:"message"`
		Description string        `json:"description"`
		Progress    int           `json:"progress"`
		Resource    NamedResource `json:"resource"`
	}

	TaskState string
)

func (this *Client) Task() *TaskService {
	return &TaskService{this.Copy()}
}

// Query returns the task object
func (this *TaskService) Query(id string) (Task, error) {
	path := fmt.Sprintf(GetTaskUriTpl, id)
	task := Task{}

	err := this.Get(path, nil, &task)

	return task, err
}

// WaitDone does a busy poll to wait for a task to reach the specified state with the timeout
func (this *TaskService) WaitDone(id string, state TaskState, to time.Duration) error {
	end := time.Now().Add(to)

	for {
		task, err := this.Query(id)
		if err != nil {
			return err
		}

		if task.State == TaskStateError {
			return errors.New(task.Message + ":" + task.Description)
		}

		if task.State == state {
			break
		}

		if time.Now().After(end) {
			return ErrTaskWaitTimeout
		}
		time.Sleep(TaskPollDelay)
	}

	return nil
}<commit_msg>more elegant task waiter<commit_after>package coprhd

import (
	"errors"
	"fmt"
	"time"
)

const (
	GetTaskUriTpl = "vdc/tasks/%s.json"

	TaskPollDelay              = time.Millisecond * 250
	TaskStatePending TaskState = "pending"
	TaskStateError   TaskState = "error"
	TaskStateReady   TaskState = "ready"
)

var (
	ErrTaskWaitTimeout = errors.New("WaitDone timeout")
)

type (
	TaskService struct {
		*Client
	}

	Task struct {
		Name        string        `json:"name"`
		Id          string        `json:"id"`
		State       TaskState     `json:"state"`
		Message     string        `json:"message"`
		Description string        `json:"description"`
		Progress    int           `json:"progress"`
		Resource    NamedResource `json:"resource"`
	}

	TaskState string
)

func (this *Client) Task() *TaskService {
	return &TaskService{this.Copy()}
}

// Query returns the task object
func (this *TaskService) Query(id string) (Task, error) {
	path := fmt.Sprintf(GetTaskUriTpl, id)
	task := Task{}

	err := this.Get(path, nil, &task)

	return task, err
}

// WaitDone does a busy poll to wait for a task to reach the specified state with the timeout
func (this *TaskService) WaitDone(id string, state TaskState, to time.Duration) error {
	timeout := time.After(to)
	timer := time.Tick(TaskPollDelay)

	for {
		task, err := this.Query(id)
		if err != nil {
			return err
		}

		if task.State == TaskStateError {
			return errors.New(task.Message + ":" + task.Description)
		}

		if task.State == state {
			return nil
		}

		select {
		case <-timer:
		case <-timeout:
			return ErrTaskWaitTimeout
		}
	}
}
{'fraction_non_alphanumeric': 0.11963383838383838, 'fraction_numerical': 0.001893939393939394, 'mean_word_length': 3.011392405063291, 'pattern_counts': {'":': 2, '<': 5, '<?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': '7066796', 'n_tokens_mistral': 1115, 'n_tokens_neox': 1033, 'n_words': 288}