<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"

	"github.com/taskcluster/httpbackoff"
	"github.com/taskcluster/taskcluster-client-go"
	"github.com/taskcluster/taskcluster-client-go/queue"
)

type taskStatusUpdate struct {
	Status     TaskStatus
	IfStatusIn map[TaskStatus]bool
	Reason     TaskUpdateReason
}

// Enumerate task status to aid life-cycle decision making
// Use strings for benefit of simple logging/reporting
const (
	aborted   TaskStatus = "Aborted"
	cancelled TaskStatus = "Cancelled"
	succeeded TaskStatus = "Succeeded"
	failed    TaskStatus = "Failed"
	errored   TaskStatus = "Errored"
	claimed   TaskStatus = "Claimed"
	reclaimed TaskStatus = "Reclaimed"
)

const (
	WorkerShutdown      TaskUpdateReason = "worker-shutdown"
	MalformedPayload    TaskUpdateReason = "malformed-payload"
	ReousrceUnavailable TaskUpdateReason = "resource-unavailable"
	InternalError       TaskUpdateReason = "internal-error"
	Superseded          TaskUpdateReason = "superseded"
	IntermittentTask    TaskUpdateReason = "intermittent-task"
)

type TaskStatusManager struct {
	request chan<- taskStatusUpdate
	err     <-chan error
	task    *TaskRun
}

func (tsm *TaskStatusManager) ReportException(reason TaskUpdateReason) error {
	tsm.request <- taskStatusUpdate{
		Status: errored,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
			aborted:   true,
		},
		Reason: reason,
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) ReportFailed() error {
	tsm.request <- taskStatusUpdate{
		Status: failed,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
			aborted:   true,
		},
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) ReportCompleted() error {
	tsm.request <- taskStatusUpdate{
		Status: succeeded,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
		},
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) Claim() error {
	tsm.request <- taskStatusUpdate{
		Status: claimed,
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) Reclaim() error {
	tsm.request <- taskStatusUpdate{
		Status: reclaimed,
		IfStatusIn: map[TaskStatus]bool{
			claimed: true,
		},
	}
	return <-tsm.err
}<commit_msg>Bug fix where task could only be claimed and then reclaimed once<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"

	"github.com/taskcluster/httpbackoff"
	"github.com/taskcluster/taskcluster-client-go"
	"github.com/taskcluster/taskcluster-client-go/queue"
)

type taskStatusUpdate struct {
	Status     TaskStatus
	IfStatusIn map[TaskStatus]bool
	Reason     TaskUpdateReason
}

// Enumerate task status to aid life-cycle decision making
// Use strings for benefit of simple logging/reporting
const (
	aborted   TaskStatus = "Aborted"
	cancelled TaskStatus = "Cancelled"
	succeeded TaskStatus = "Succeeded"
	failed    TaskStatus = "Failed"
	errored   TaskStatus = "Errored"
	claimed   TaskStatus = "Claimed"
	reclaimed TaskStatus = "Reclaimed"
)

const (
	WorkerShutdown      TaskUpdateReason = "worker-shutdown"
	MalformedPayload    TaskUpdateReason = "malformed-payload"
	ReousrceUnavailable TaskUpdateReason = "resource-unavailable"
	InternalError       TaskUpdateReason = "internal-error"
	Superseded          TaskUpdateReason = "superseded"
	IntermittentTask    TaskUpdateReason = "intermittent-task"
)

type TaskStatusManager struct {
	request chan<- taskStatusUpdate
	err     <-chan error
	task    *TaskRun
}

func (tsm *TaskStatusManager) ReportException(reason TaskUpdateReason) error {
	tsm.request <- taskStatusUpdate{
		Status: errored,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
			aborted:   true,
		},
		Reason: reason,
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) ReportFailed() error {
	tsm.request <- taskStatusUpdate{
		Status: failed,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
			aborted:   true,
		},
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) ReportCompleted() error {
	tsm.request <- taskStatusUpdate{
		Status: succeeded,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
		},
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) Claim() error {
	tsm.request <- taskStatusUpdate{
		Status: claimed,
	}
	return <-tsm.err
}

func (tsm *TaskStatusManager) Reclaim() error {
	tsm.request <- taskStatusUpdate{
		Status: reclaimed,
		IfStatusIn: map[TaskStatus]bool{
			claimed:   true,
			reclaimed: true,
		},
	}
	return <-tsm.err
}
{'fraction_non_alphanumeric': 0.10171759982154807, 'fraction_numerical': 0.0, 'mean_word_length': 4.078142695356738, 'pattern_counts': {'":': 0, '<': 27, '<?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': '1247924', 'n_tokens_mistral': 1610, 'n_tokens_neox': 1495, 'n_words': 353}