134 lines
3.7 KiB
Go
134 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
_ "github.com/go-sql-driver/mysql"
|
|
_ "github.com/taosdata/driver-go/v3/taosWS"
|
|
"lingniu/vehicle-data-platform/apps/api/internal/config"
|
|
"lingniu/vehicle-data-platform/apps/api/internal/dailygeo"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
func main() {
|
|
if e := run(); e != nil {
|
|
log.Fatal(e)
|
|
}
|
|
}
|
|
func run() error {
|
|
mode := flag.String("mode", "status", "status, backfill, resolve, or live")
|
|
from := flag.String("from", "", "first historical date, defaults to first hydrogen day")
|
|
to := flag.String("to", "", "last historical date, defaults to yesterday")
|
|
concurrency := flag.Int("concurrency", 3, "maximum concurrent geocoding requests (1-8)")
|
|
flag.Parse()
|
|
cfg := config.Load()
|
|
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer cancel()
|
|
db, e := sql.Open("mysql", cfg.MySQLDSN)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
defer db.Close()
|
|
db.SetMaxOpenConns(12)
|
|
if *from == "" {
|
|
if e = db.QueryRowContext(ctx, `SELECT COALESCE(DATE_FORMAT(MIN(stat_date),'%Y-%m-%d'),'') FROM vehicle_open_daily_energy WHERE energy_type='HYDROGEN'`).Scan(from); e != nil {
|
|
return e
|
|
}
|
|
}
|
|
if *to == "" {
|
|
*to = time.Now().In(dailygeo.Shanghai).AddDate(0, 0, -1).Format("2006-01-02")
|
|
}
|
|
first, e := time.ParseInLocation("2006-01-02", *from, dailygeo.Shanghai)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
last, e := time.ParseInLocation("2006-01-02", *to, dailygeo.Shanghai)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
if first.After(last) {
|
|
return fmt.Errorf("invalid date range")
|
|
}
|
|
if *mode == "status" {
|
|
return printStatus(ctx, db, *from, *to)
|
|
}
|
|
if cfg.AMapAPIKey == "" {
|
|
return fmt.Errorf("AMAP_API_KEY required")
|
|
}
|
|
td, e := sql.Open(cfg.TDengineDriver, cfg.TDengineDSN)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
defer td.Close()
|
|
td.SetMaxOpenConns(2)
|
|
w := dailygeo.New(db, td, cfg.TDengineDatabase, &dailygeo.AMap{Key: cfg.AMapAPIKey})
|
|
w.Concurrency = *concurrency
|
|
if *mode == "live" {
|
|
w.Run(ctx)
|
|
return ctx.Err()
|
|
}
|
|
if *mode != "backfill" && *mode != "resolve" {
|
|
return fmt.Errorf("invalid mode")
|
|
}
|
|
return w.WithLock(ctx, "vehicle_daily_geography_backfill", func() error {
|
|
if *mode == "backfill" {
|
|
for d := first; !d.After(last); d = d.AddDate(0, 0, 1) {
|
|
rctx, c := context.WithTimeout(ctx, 90*time.Second)
|
|
n, e := w.RefreshDay(rctx, d.Format("2006-01-02"))
|
|
c()
|
|
if e != nil {
|
|
return e
|
|
}
|
|
log.Printf("daily_geography_seed date=%s points=%d", d.Format("2006-01-02"), n)
|
|
}
|
|
}
|
|
for {
|
|
n, failed, e := w.ResolvePending(ctx, *from, *to, 1000)
|
|
log.Printf("daily_geography_batch resolved=%d failed=%d error=%v", n, failed, e)
|
|
if ctx.Err() != nil {
|
|
return ctx.Err()
|
|
}
|
|
if e != nil && failed == 0 {
|
|
return e
|
|
}
|
|
if n+failed == 0 {
|
|
break
|
|
}
|
|
}
|
|
return printStatus(ctx, db, *from, *to)
|
|
})
|
|
}
|
|
func printStatus(ctx context.Context, db *sql.DB, from, to string) error {
|
|
rows, e := db.QueryContext(ctx, `SELECT status,COUNT(*) FROM vehicle_daily_geography WHERE stat_date BETWEEN ? AND ? GROUP BY status`, from, to)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
defer rows.Close()
|
|
counts := map[string]int{}
|
|
for rows.Next() {
|
|
var s string
|
|
var n int
|
|
if e = rows.Scan(&s, &n); e != nil {
|
|
return e
|
|
}
|
|
counts[s] = n
|
|
}
|
|
if e = rows.Err(); e != nil {
|
|
return e
|
|
}
|
|
rows.Close()
|
|
var missing int
|
|
e = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM vehicle_open_daily_energy h LEFT JOIN vehicle_daily_geography g ON g.vin=h.vin COLLATE utf8mb4_unicode_ci AND g.stat_date=h.stat_date WHERE h.energy_type='HYDROGEN' AND h.stat_date BETWEEN ? AND ? AND g.vin IS NULL`, from, to).Scan(&missing)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
return json.NewEncoder(os.Stdout).Encode(map[string]any{"from": from, "to": to, "counts": counts, "hydrogenDaysMissing": missing})
|
|
}
|