-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprogress.go
134 lines (113 loc) · 3.67 KB
/
progress.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
131
132
133
134
package ortfodb
import (
"encoding/json"
"fmt"
"os"
"strings"
ll "github.com/ewen-lbh/label-logger-go"
)
var currentlyBuildingWorkIDs []string
var builtWorksCount int
var worksToBuildCount int
type BuildPhase string
const (
PhaseThumbnails BuildPhase = "Thumbnailing"
PhaseMediaAnalysis BuildPhase = "Analyzing"
PhaseBuilding BuildPhase = "Building"
PhaseBuilt BuildPhase = "Built"
PhaseUnchanged BuildPhase = "Reusing"
)
func (phase BuildPhase) String() string {
return string(phase)
}
func padPhaseVerb(phase BuildPhase) string {
// length of longest phase verb: "Thumbnailing", plus some padding
return fmt.Sprintf("%15s", phase)
}
func (ctx *RunContext) StartProgressBar(total int) {
worksToBuildCount = total
ll.StartProgressBar(total, "Building", "magenta")
}
func (ctx *RunContext) IncrementProgress() {
builtWorksCount++
if BuildIsFinished() {
ll.Log("Finished", "green", "compiling to %s\n", ctx.OutputDatabaseFile)
os.Remove(ctx.ProgressInfoFile)
}
ll.IncrementProgressBar()
if BuildIsFinished() {
ll.StopProgressBar()
}
}
func BuildIsFinished() bool {
return ll.ProgressBarFinished() || builtWorksCount >= worksToBuildCount
}
// Status updates the current progress and writes the progress to a file if --write-progress is set.
func (ctx *RunContext) Status(workID string, phase BuildPhase, details ...string) {
var color string
switch phase {
case PhaseBuilt:
color = "light_green"
case PhaseUnchanged:
color = "dim"
default:
color = "cyan"
}
formattedDetails := ""
if len(details) > 0 {
formattedDetails = fmt.Sprintf(" [dim]%s[reset]", strings.Join(details, " "))
}
ll.Log(phase.String(), color, "%s%s", workID, formattedDetails)
if phase == PhaseBuilt || phase == PhaseUnchanged {
for i, id := range currentlyBuildingWorkIDs {
if id == workID {
currentlyBuildingWorkIDs = append(currentlyBuildingWorkIDs[:i], currentlyBuildingWorkIDs[i+1:]...)
break
}
}
ctx.IncrementProgress()
} else if phase == PhaseBuilding {
currentlyBuildingWorkIDs = append(currentlyBuildingWorkIDs, workID)
}
if err := ctx.appendToProgressFile(workID, phase, details...); err != nil {
ll.WarnDisplay("could not append progress info to file", err)
}
}
// ProgressInfoEvent represents an event that is appended to the progress JSONLines file.
type ProgressInfoEvent struct {
// WorksDone is the number of works that have been built
WorksDone int `json:"works_done"`
// WorksTotal is the total number of works that will be built
WorksTotal int `json:"works_total"`
WorkID string `json:"work_id"`
Phase BuildPhase `json:"phase"`
Details []string `json:"details"`
}
func (ctx *RunContext) appendToProgressFile(workID string, phase BuildPhase, details ...string) error {
if ctx.ProgressInfoFile == "" {
ll.Debug("not writing progress info to file because --write-progress is not set")
return nil
}
event := ProgressInfoEvent{
WorksDone: builtWorksCount,
WorksTotal: worksToBuildCount,
WorkID: workID,
Phase: phase,
Details: details,
}
ll.Debug("Appending event %#v to progress file %s", event, ctx.ProgressInfoFile)
// append JSON marshalled event to file
file, err := os.OpenFile(ctx.ProgressInfoFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("while opening progress info file at %s: %w", ctx.ProgressInfoFile, err)
}
marshaled, err := json.Marshal(event)
if err != nil {
return fmt.Errorf("while converting event to JSON (event is %#v): %w", event, err)
}
_, err = file.WriteString(fmt.Sprintf("%s\n", marshaled))
if err != nil {
return fmt.Errorf("while appending progress info event to %s: %w", ctx.ProgressInfoFile, err)
}
return nil
}