in maintner/maintnerd/maintnerd.go [73:256]
func main() {
https.RegisterFlags(flag.CommandLine)
flag.Parse()
ctx := context.Background()
if *dataDir == "" {
*dataDir = filepath.Join(os.Getenv("HOME"), "var", "maintnerd")
if *bucket == "" {
if err := os.MkdirAll(*dataDir, 0755); err != nil {
log.Fatal(err)
}
log.Printf("Storing data in implicit directory %s", *dataDir)
}
}
if *migrateGCSFlag && *bucket == "" {
log.Fatalf("--bucket flag required with --migrate-disk-to-gcs")
}
type storage interface {
maintner.MutationSource
maintner.MutationLogger
}
var logger storage
corpus := new(maintner.Corpus)
switch *config {
case "":
// Nothing
case "devgo":
dir := godata.Dir()
if err := os.MkdirAll(dir, 0700); err != nil {
log.Fatal(err)
}
log.Printf("Syncing from https://maintner.golang.org/logs to %s", dir)
mutSrc := maintner.NewNetworkMutationSource("https://maintner.golang.org/logs", dir)
for evt := range mutSrc.GetMutations(ctx) {
if evt.Err != nil {
log.Fatal(evt.Err)
}
if evt.End {
break
}
}
syncProdToDevMutationLogs()
log.Printf("Synced from https://maintner.golang.org/logs.")
setGoConfig()
case "go":
if err := gitauth.Init(); err != nil {
log.Fatalf("gitauth: %v", err)
}
setGoConfig()
case "godata":
setGodataConfig()
var err error
log.Printf("Using godata corpus...")
corpus, err = godata.Get(ctx)
if err != nil {
log.Fatal(err)
}
default:
log.Fatalf("unknown --config=%s", *config)
}
if *genMut {
if *bucket != "" {
ctx := context.Background()
gl, err := gcslog.NewGCSLog(ctx, *bucket)
if err != nil {
log.Fatalf("newGCSLog: %v", err)
}
gl.SetDebug(*debug)
gl.RegisterHandlers(http.DefaultServeMux)
if *migrateGCSFlag {
diskLog := maintner.NewDiskMutationLogger(*dataDir)
if err := gl.CopyFrom(diskLog); err != nil {
log.Fatalf("migrate: %v", err)
}
log.Printf("Success.")
return
}
logger = gl
} else {
logger = maintner.NewDiskMutationLogger(*dataDir)
}
corpus.EnableLeaderMode(logger, *dataDir)
}
if *debug {
corpus.SetDebug()
}
corpus.SetVerbose(*verbose)
if *watchGithub != "" {
if *githubRateLimit > 0 {
limit := rate.Every(time.Second / time.Duration(*githubRateLimit))
corpus.SetGitHubLimiter(rate.NewLimiter(limit, *githubRateLimit))
}
for _, pair := range strings.Split(*watchGithub, ",") {
splits := strings.SplitN(pair, "/", 2)
if len(splits) != 2 || splits[1] == "" {
log.Fatalf("Invalid github repo: %s. Should be 'owner/repo,owner2/repo2'", pair)
}
token, err := getGithubToken(ctx)
if err != nil {
log.Fatalf("getting github token: %v", err)
}
corpus.TrackGitHub(splits[0], splits[1], token)
}
}
if *watchGerrit != "" {
for _, project := range strings.Split(*watchGerrit, ",") {
// token may be empty, that's OK.
corpus.TrackGerrit(project)
}
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
t0 := time.Now()
if logger != nil {
if err := corpus.Initialize(ctx, logger); err != nil {
// TODO: if Initialize only partially syncs the data, we need to delete
// whatever files it created, since Github returns events newest first
// and we use the issue updated dates to check whether we need to keep
// syncing.
log.Fatal(err)
}
initDur := time.Since(t0)
runtime.GC()
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
log.Printf("Loaded data in %v. Memory: %v MB (%v bytes)", initDur, ms.HeapAlloc>>20, ms.HeapAlloc)
}
if *initQuit {
return
}
if *syncQuit {
if err := corpus.Sync(ctx); err != nil {
log.Fatalf("corpus.Sync = %v", err)
}
if err := corpus.Check(); err != nil {
log.Fatalf("post-Sync Corpus.Check = %v", err)
}
return
}
if *pubsub != "" {
corpus.StartPubSubHelperSubscribe(*pubsub)
}
grpcServer := grpc.NewServer()
apipb.RegisterMaintnerServiceServer(grpcServer, maintapi.NewAPIService(corpus))
http.Handle("/apipb.MaintnerService/", grpcServer)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
return
}
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
io.WriteString(w, `<html>
<body>
<p>
This is <a href='https://godoc.org/golang.org/x/build/maintner/maintnerd'>maintnerd</a>,
the <a href='https://godoc.org/golang.org/x/build/maintner'>maintner</a> server.
See the <a href='https://godoc.org/golang.org/x/build/maintner/godata'>godata package</a> for
a client.
</p>
<ul>
<li><a href='/logs'>/logs</a>
</ul>
</body></html>
`)
})
if *genMut {
go func() { log.Fatalf("Corpus.SyncLoop = %v", corpus.SyncLoop(ctx)) }()
}
log.Fatalln(https.ListenAndServe(ctx, http.DefaultServeMux))
}