-
Notifications
You must be signed in to change notification settings - Fork 12
/
dependency.go
130 lines (118 loc) · 4.28 KB
/
dependency.go
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
// Copyright © 2016-2018 Genome Research Limited
// Author: Sendu Bala <sb10@sanger.ac.uk>.
//
// This file is part of wr.
//
// wr is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// wr is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with wr. If not, see <http://www.gnu.org/licenses/>.
package jobqueue
// This file contains the dependency related code.
// Dependencies is a slice of *Dependency, for use in Job.Dependencies. It
// describes the jobs that must be complete before the Job you associate this
// with will start.
type Dependencies []*Dependency
// incompleteJobKeys converts the constituent Dependency structs in to internal
// job keys that uniquely identify the jobs we are dependent upon. Note that if
// you have dependencies that are specified with DepGroups, then you should re-
// call this and update every time a new Job is added with with one of our
// DepGroups() in its *Job.DepGroups. It will only return keys for jobs that
// are incomplete (they could have been Archive()d in the past if they are now
// being re-run).
func (d Dependencies) incompleteJobKeys(db *db) ([]string, error) {
// we initially store in a map to avoid duplicates
jobKeys := make(map[string]bool)
for _, dep := range d {
keys, err := dep.incompleteJobKeys(db)
if err != nil {
return []string{}, err
}
for _, key := range keys {
jobKeys[key] = true
}
}
keys := make([]string, len(jobKeys))
i := 0
for key := range jobKeys {
keys[i] = key
i++
}
return keys, nil
}
// DepGroups returns all the DepGroups of our constituent Dependency structs.
func (d Dependencies) DepGroups() []string {
var depGroups []string
for _, dep := range d {
if dep.DepGroup != "" {
depGroups = append(depGroups, dep.DepGroup)
}
}
return depGroups
}
// Stringify converts our constituent Dependency structs in to a slice of
// strings, each of which could be JobEssence or DepGroup based.
func (d Dependencies) Stringify() []string {
var strings []string
for _, dep := range d {
if dep.DepGroup != "" {
strings = append(strings, dep.DepGroup)
} else if dep.Essence != nil {
strings = append(strings, dep.Essence.Stringify())
}
}
return strings
}
// Dependency is a struct that describes a Job purely in terms of a JobEssence,
// or in terms of a Job's DepGroup, for use in Dependencies. If DepGroup is
// specified, then Essence is ignored.
type Dependency struct {
Essence *JobEssence
DepGroup string
}
// incompleteJobKeys calculates the job keys that this dependency refers to. For
// a Dependency made with Essence, you will get a single key which will be the
// same key you'd get from *Job.key() on a Job made with the same essence.
// For a Dependency made with a DepGroup, you will get the *Job.key()s of all
// the jobs in the queue and database that have that DepGroup in their
// DepGroups. You will only get keys for jobs that are currently in the queue.
func (d *Dependency) incompleteJobKeys(db *db) ([]string, error) {
if d.DepGroup != "" {
keys, err := db.retrieveIncompleteJobKeysByDepGroup(d.DepGroup)
return keys, err
}
if d.Essence != nil {
jobKey := d.Essence.Key()
live, err := db.checkIfLive(jobKey)
if err != nil {
return []string{}, err
}
if live {
return []string{jobKey}, nil
}
}
return []string{}, nil
}
// NewEssenceDependency makes it a little easier to make a new *Dependency based
// on Cmd+Cwd, for use in NewDependencies(). Leave cwd as an empty string if the
// job you are describing does not have CwdMatters true.
func NewEssenceDependency(cmd string, cwd string) *Dependency {
return &Dependency{
Essence: &JobEssence{Cmd: cmd, Cwd: cwd},
}
}
// NewDepGroupDependency makes it a little easier to make a new *Dependency
// based on a dep group, for use in NewDependencies().
func NewDepGroupDependency(depgroup string) *Dependency {
return &Dependency{
DepGroup: depgroup,
}
}