summaryrefslogtreecommitdiff
path: root/pkg/queue/queue.go
blob: b61d43b01a50f82204ce5dc34bd0089bf81e8171 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package queue

import (
	"errors"
	"fmt"
	"time"

	"github.com/isacikgoz/gitbatch/pkg/git"
)

// Job relates the type of the operation and the entity
type Job struct {
	JobType JobType
	Entity  *git.RepoEntity
}

// JobQueue holds the slice of Jobs
type JobQueue struct {
	series []*Job
}

// JobType is the a git operation supported
type JobType string

const (
	// Fetch is wrapper of git fetch command
	Fetch JobType = "fetch"
	// Pull is wrapper of git pull command
	Pull JobType = "pull"
	// Merge is wrapper of git merge command
	Merge JobType = "merge"
)

// CreateJob es its name implies creates a job struct and return its pointer
func CreateJob() (j *Job, err error) {
	fmt.Println("Job created.")
	return j, nil
}

// starts the job
func (job *Job) start() error {
	job.Entity.State = git.Working
	// added for testing, TODO: remove
	time.Sleep(time.Second)
	// TODO: Handle errors?
	switch mode := job.JobType; mode {
	case Fetch:
		if err := job.Entity.Fetch(); err != nil {
			job.Entity.State = git.Fail
			return nil
		}
		job.Entity.RefreshPushPull()
		job.Entity.State = git.Success
	case Pull:
		if err := job.Entity.Pull(); err != nil {
			job.Entity.State = git.Fail
			return nil
		}
		job.Entity.RefreshPushPull()
		job.Entity.State = git.Success
	case Merge:
		if err := job.Entity.Merge(); err != nil {
			job.Entity.State = git.Fail
			return nil
		}
		job.Entity.RefreshPushPull()
		job.Entity.State = git.Success
	default:
		job.Entity.State = git.Available
		return nil
	}
	return nil
}

// CreateJobQueue creates a jobqueue struct and initialize its slice then return
// its pointer
func CreateJobQueue() (jobQueue *JobQueue) {
	s := make([]*Job, 0)
	return &JobQueue{
		series: s,
	}
}

// AddJob adds a job to the queue
func (jobQueue *JobQueue) AddJob(j *Job) error {
	for _, job := range jobQueue.series {
		if job.Entity.RepoID == j.Entity.RepoID && job.JobType == j.JobType {
			return errors.New("Same job already is in the queue")
		}
	}
	jobQueue.series = append(jobQueue.series, j)
	return nil
}

// StartNext starts the next job in the queue
func (jobQueue *JobQueue) StartNext() (j *Job, finished bool, err error) {
	finished = false
	if len(jobQueue.series) < 1 {
		finished = true
		return nil, finished, nil
	}
	i := len(jobQueue.series) - 1
	lastJob := jobQueue.series[i]
	jobQueue.series = jobQueue.series[:i]
	if err = lastJob.start(); err != nil {
		return lastJob, finished, err
	}
	return lastJob, finished, nil
}

// RemoveFromQueue deletes the given entity and its job from the queue
// TODO: it is not safe if the job has been started
func (jobQueue *JobQueue) RemoveFromQueue(entity *git.RepoEntity) error {
	removed := false
	for i, job := range jobQueue.series {
		if job.Entity.RepoID == entity.RepoID {
			jobQueue.series = append(jobQueue.series[:i], jobQueue.series[i+1:]...)
			removed = true
		}
	}
	if !removed {
		return errors.New("There is no job with given repoID")
	}
	return nil
}

// IsInTheQueue function; since the job and entity is not tied with its own
// struct, this function returns true if that entity is in the queue along with
// the jobs type
func (jobQueue *JobQueue) IsInTheQueue(entity *git.RepoEntity) (inTheQueue bool, jt JobType) {
	inTheQueue = false
	for _, job := range jobQueue.series {
		if job.Entity.RepoID == entity.RepoID {
			inTheQueue = true
			jt = job.JobType
		}
	}
	return inTheQueue, jt
}