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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
package steam
import (
"sync"
"time"
)
// JobStatus provides specific information about an individual job
type Job struct {
action string
target *Game
running bool
start *time.Time
errors []error
// If applicablle
size *int64
transferred *int64
eta *time.Duration
m sync.Mutex
}
// Action is a short string describing the action, i.e. "packaging", "deleting"
func (j *Job) Action() string {
j.m.Lock()
defer j.m.Unlock()
return j.action
}
// Target returns the game that is the target of the action
func (j *Job) Target() *Game {
j.m.Lock()
defer j.m.Unlock()
return j.target
}
// IsRunning returns true if the job is currently running, otherwise false
func (j *Job) IsRunning() bool {
j.m.Lock()
defer j.m.Unlock()
return j.running
}
// StartTime returns the time in which the job started
func (j *Job) StartTime() *time.Time {
j.m.Lock()
defer j.m.Unlock()
return j.start
}
func (j *Job) Errors() []error {
j.m.Lock()
defer j.m.Unlock()
return j.errors
}
// newJob sets up a job of action for the target Game
func newJob(action string, target *Game) *Job {
t := time.Now()
return &Job{
action: action,
target: target,
running: true,
start: &t,
}
}
func (j *Job) setSize(size int64) {
j.m.Lock()
defer j.m.Unlock()
j.size = &size
}
// GetSize returns the size set if applicable for the operation
func (j *Job) GetSize() *int64 {
j.m.Lock()
defer j.m.Unlock()
return j.size
}
func (j *Job) setTransferred(transferred int64) {
j.m.Lock()
defer j.m.Unlock()
j.transferred = &transferred
}
// GetTransferred returns the transferred set if applicable for the operation
func (j *Job) GetTransferred() *int64 {
j.m.Lock()
defer j.m.Unlock()
return j.transferred
}
// setETA sets the eta to the speicifed duration
func (j *Job) setETA(d time.Duration) {
j.m.Lock()
defer j.m.Unlock()
j.eta = &d
}
// GetETA returns the ETA to completion as a *time.Duration. nil represents
// when
func (j *Job) GetETA() *time.Duration {
j.m.Lock()
defer j.m.Unlock()
return j.eta
}
// done sets running to false
func (j *Job) done() {
j.m.Lock()
defer j.m.Unlock()
j.running = false
}
// addError appends an error to the internal slice of errors
func (j *Job) addError(err error) {
j.m.Lock()
defer j.m.Unlock()
j.errors = append(j.errors, err)
}
// Jobs is by the Library to determine whether or not we currently have any
// jobs running on this library, as well as to give some history as to
// what jobs have been run previously
type Jobs struct {
running []*Job
previous []*Job
m sync.Mutex
}
func (jobs *Jobs) scan() {
jobs.m.Lock()
defer jobs.m.Unlock()
running := []*Job{}
notrunning := []*Job{}
for _, job := range jobs.running {
if job == nil {
continue
}
if job.IsRunning() == true {
running = append(running, job)
} else {
notrunning = append(notrunning, job)
}
}
if len(notrunning) > 0 {
jobs.previous = append(jobs.previous, notrunning...)
}
jobs.running = running
}
// Running returns true if any job is currently running, otherwise false
func (jobs *Jobs) Running() bool {
jobs.scan()
jobs.m.Lock()
defer jobs.m.Unlock()
if len(jobs.running) == 0 {
return false
}
return true
}
// GetJobs returns all of the jobs regardless of their state
func (jobs *Jobs) GetJobs() []*Job {
jobs.scan()
jobs.m.Lock()
defer jobs.m.Unlock()
return append(jobs.running, jobs.previous...)
}
// GetRunningJobs returns all of the running jobs
func (jobs *Jobs) GetRunningJobs() []*Job {
jobs.scan()
jobs.m.Lock()
defer jobs.m.Unlock()
return jobs.running
}
// GetStoppedJobs returns all of the stopped jobs
func (jobs *Jobs) GetStoppedJobs() []*Job {
jobs.scan()
jobs.m.Lock()
defer jobs.m.Unlock()
return jobs.previous
}
// addJob adds a job to the internal slice
func (jobs *Jobs) addJob(j *Job) {
jobs.m.Lock()
jobs.running = append(jobs.running, j)
jobs.m.Unlock()
jobs.scan()
}
|