-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathmigrate.go
90 lines (77 loc) · 2 KB
/
migrate.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
package processor
import (
"context"
"flag"
"fmt"
"sync"
"cloud.google.com/go/datastore"
"github.com/web-platform-tests/wpt.fyi/shared"
"google.golang.org/api/iterator"
)
var (
dryRun = flag.Bool("dry-run", false, "Only print out runs that would be affected")
projectID = flag.String("project", "wptdashboard-staging", "Google Cloud project")
)
// ConditionUnsatisfied is a non-fatal error when a run does not need to be processed.
type ConditionUnsatisfied struct{}
func (e ConditionUnsatisfied) Error() string {
return "Condition not satisfied"
}
func ProcessRun(ctx context.Context, runsProcessor Runs, dsClient *datastore.Client, key *datastore.Key, wg *sync.WaitGroup) {
defer wg.Done()
var run shared.TestRun
_, err := dsClient.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
err := tx.Get(key, &run)
if err != nil {
return err
}
if runsProcessor.ShouldProcessRun(&run) {
if *dryRun {
return nil
}
return runsProcessor.ProcessRun(tx, key, &run)
}
return ConditionUnsatisfied{}
})
if err != nil {
_, ok := err.(ConditionUnsatisfied)
if !ok {
panic(err)
} else {
return
}
}
fmt.Printf("Processed TestRun %s (%s %s)\n", key.String(), run.BrowserName, run.BrowserVersion)
}
// MigrateData handles all the loading and transactions across the full
// datastore. It should be called from a main(), e.g.
//
// func main() {
// p := experimentalLabeller{}
// processor.MigrateData(p)
// }
func MigrateData(runsProcessor Runs) {
flag.Parse()
if *dryRun {
fmt.Println("Dry running; data will NOT be modified...")
}
ctx := context.Background()
dsClient, err := datastore.NewClient(ctx, *projectID)
if err != nil {
panic(err)
}
query := datastore.NewQuery("TestRun").Order("-TimeStart").KeysOnly()
var wg sync.WaitGroup
for t := dsClient.Run(ctx, query); ; {
key, err := t.Next(nil)
if err == iterator.Done {
break
}
if err != nil {
panic(err)
}
wg.Add(1)
go ProcessRun(ctx, runsProcessor, dsClient, key, &wg)
}
wg.Wait()
}