Skip to content

Commit a400cce

Browse files
committed
WIP
1 parent c664db4 commit a400cce

File tree

3 files changed

+94
-13
lines changed

3 files changed

+94
-13
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ require (
171171

172172
require (
173173
cloud.google.com/go/longrunning v0.3.0 // indirect
174+
github.com/coder/flog v1.0.0 // indirect
174175
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
176+
github.com/gocarina/gocsv v0.0.0-20230123225133-763e25b40669 // indirect
175177
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
176178
github.com/hashicorp/go-hclog v1.2.1 // indirect
177179
github.com/hashicorp/go-plugin v1.4.4 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
355355
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
356356
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
357357
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
358+
github.com/coder/flog v1.0.0 h1:gqr4jYDQWYmsvFD0RV6Vs+SAj1Kbn0HGlV7UghfxP+8=
359+
github.com/coder/flog v1.0.0/go.mod h1:UQlQvrkJBvnRGo69Le8E24Tcl5SJleAAR7gYEHzAmdQ=
358360
github.com/coder/glog v1.0.1-0.20220322161911-7365fe7f2cd1 h1:UqBrPWSYvRI2s5RtOul20JukUEpu4ip9u7biBL+ntgk=
359361
github.com/coder/glog v1.0.1-0.20220322161911-7365fe7f2cd1/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
360362
github.com/coder/retry v1.3.0 h1:5lAAwt/2Cm6lVmnfBY7sOMXcBOwcwJhmV5QGSELIVWY=
@@ -772,6 +774,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
772774
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
773775
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
774776
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
777+
github.com/gocarina/gocsv v0.0.0-20230123225133-763e25b40669 h1:MvZzCA/mduVWoBSVKJeMdv+AqXQmZZ8i6p8889ejt/Y=
778+
github.com/gocarina/gocsv v0.0.0-20230123225133-763e25b40669/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
775779
github.com/gocql/gocql v0.0.0-20210515062232-b7ef815b4556/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY=
776780
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
777781
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=

scripts/aistart/loadcsv.go

Lines changed: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,81 @@ package main
22

33
import (
44
"database/sql"
5-
"fmt"
65
"os"
76
"time"
87

9-
"github.com/coder/flog"
8+
"github.com/gocarina/gocsv"
109
"github.com/spf13/cobra"
10+
"golang.org/x/xerrors"
11+
12+
"github.com/coder/flog"
1113
)
1214

1315
func connectDB() (*sql.DB, error) {
1416
const envKey = "POSTGRES_URL"
1517
url := os.Getenv(envKey)
1618
if url == "" {
17-
return nil, fmt.Errorf("no $%v provided", envKey)
19+
return nil, xerrors.Errorf("no $%v provided", envKey)
1820
}
1921

2022
return sql.Open("postgres", url)
2123
}
2224

25+
type trainingRow struct {
26+
WorkspaceID string `csv:"workspace_id"`
27+
// HourOfDay ranges from 0 to 23
28+
HourOfDay int `csv:"hour"`
29+
// Day of Week ranges from 0 to 6
30+
DayOfWeek int `csv:"day"`
31+
Used bool `csv:"used"`
32+
}
33+
34+
type dbRow struct {
35+
Time time.Time
36+
WorkspaceID string
37+
}
38+
39+
func (db dbRow) convert(used bool) trainingRow {
40+
return trainingRow{
41+
WorkspaceID: db.WorkspaceID,
42+
HourOfDay: db.Time.Hour(),
43+
DayOfWeek: int(db.Time.Weekday()),
44+
Used: used,
45+
}
46+
}
47+
48+
// generateTrainingRows accepts sparse input data from the DB and creates
49+
// trainingRows suitable to enter a prediction model.
50+
func generateTrainingRows(rs []dbRow) []trainingRow {
51+
workspaceIDs := make(map[string]struct{})
52+
for _, r := range rs {
53+
workspaceIDs[r.WorkspaceID] = struct{}{}
54+
}
55+
56+
var trainingRows []trainingRow
57+
58+
last := rs[0].Time
59+
for _, r := range rs {
60+
if !r.Time.Equal(last) && !last.IsZero() {
61+
// We just skipped a time-slot, we must fill in the blanks.
62+
for last.Before(r.Time) {
63+
last = last.Add(time.Hour)
64+
for wid := range workspaceIDs {
65+
trainingRows = append(trainingRows, trainingRow{
66+
WorkspaceID: wid,
67+
HourOfDay: last.Hour(),
68+
DayOfWeek: int(last.Weekday()),
69+
Used: false,
70+
})
71+
}
72+
}
73+
}
74+
trainingRows = append(trainingRows, r.convert(true))
75+
}
76+
77+
return trainingRows
78+
}
79+
2380
func loadTrainingCSV() *cobra.Command {
2481
return &cobra.Command{
2582
Use: "load-training-csv",
@@ -28,28 +85,46 @@ func loadTrainingCSV() *cobra.Command {
2885
if err != nil {
2986
return err
3087
}
31-
const q = `SELECT
32-
date_trunc('hour', created_at) at_hour
88+
const q = `
89+
SELECT
90+
date_trunc('hour', ag.created_at) at_hour,
91+
workspace_id
3392
FROM
34-
agent_stats
93+
agent_stats ag
94+
JOIN workspaces w ON
95+
w.id = ag.workspace_id
96+
WHERE
97+
NOT w.deleted
3598
GROUP BY
36-
workspace_id, at_hour;
99+
workspace_id,
100+
user_id,
101+
at_hour
102+
ORDER BY
103+
at_hour ASC;
37104
`
38105
rows, err := db.Query(q)
39106
if err != nil {
40107
return err
41108
}
42109

43-
var times []time.Time
110+
var rs []dbRow
44111
for rows.Next() {
45-
var t time.Time
46-
err = rows.Scan(&t)
112+
var r dbRow
113+
err = rows.Scan(&r.Time, &r.WorkspaceID)
47114
if err != nil {
48-
return nil
115+
return err
49116
}
50-
times = append(times, t)
117+
rs = append(rs, r)
51118
}
52-
flog.Info("times: %+v", times)
119+
err = rows.Err()
120+
if err != nil {
121+
return err
122+
}
123+
124+
flog.Info("loaded %v rows", len(rs))
125+
trainingRows := generateTrainingRows(rs)
126+
flog.Info("generated %v training rows", len(trainingRows))
127+
gocsv.Marshal(trainingRows, os.Stdout)
53128
return nil
54129
},
55130
}

0 commit comments

Comments
 (0)