summaryrefslogtreecommitdiff
path: root/pkg/queue/queue.go
blob: 091fa8407eb492a182c51d38aa699c9953440245 (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
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
}

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

type JobType string

const (
	Fetch JobType = "fetch"
	Pull  JobType = "pull"
	Merge JobType = "merge"
)

// 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
}

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

// add 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
}

// start the next job of 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
}

// delete it 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
}

// 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
}