golang.org/x/playground@v0.0.0-20230418134305-14ebe15bcd59/main.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "context" 9 "flag" 10 "fmt" 11 "net/http" 12 "os" 13 14 "cloud.google.com/go/compute/metadata" 15 "cloud.google.com/go/datastore" 16 "golang.org/x/playground/internal/metrics" 17 ) 18 19 var log = newStdLogger() 20 21 var ( 22 runtests = flag.Bool("runtests", false, "Run integration tests instead of Playground server.") 23 backendURL = flag.String("backend-url", "", "URL for sandbox backend that runs Go binaries.") 24 ) 25 26 func main() { 27 flag.Parse() 28 s, err := newServer(func(s *server) error { 29 pid := projectID() 30 if pid == "" { 31 s.db = &inMemStore{} 32 } else { 33 c, err := datastore.NewClient(context.Background(), pid) 34 if err != nil { 35 return fmt.Errorf("could not create cloud datastore client: %v", err) 36 } 37 s.db = cloudDatastore{client: c} 38 } 39 if caddr := os.Getenv("MEMCACHED_ADDR"); caddr != "" { 40 s.cache = newGobCache(caddr) 41 log.Printf("App (project ID: %q) is caching results", pid) 42 } else { 43 s.cache = (*gobCache)(nil) // Use a no-op cache implementation. 44 log.Printf("App (project ID: %q) is NOT caching results", pid) 45 } 46 s.log = log 47 if gotip := os.Getenv("GOTIP"); gotip == "true" { 48 s.gotip = true 49 } 50 execpath, _ := os.Executable() 51 if execpath != "" { 52 if fi, _ := os.Stat(execpath); fi != nil { 53 s.modtime = fi.ModTime() 54 } 55 } 56 eh, err := newExamplesHandler(s.gotip, s.modtime) 57 if err != nil { 58 return err 59 } 60 s.examples = eh 61 return nil 62 }, enableMetrics) 63 if err != nil { 64 log.Fatalf("Error creating server: %v", err) 65 } 66 67 if *runtests { 68 s.test() 69 return 70 } 71 if *backendURL != "" { 72 // TODO(golang.org/issue/25224) - Remove environment variable and use a flag. 73 os.Setenv("SANDBOX_BACKEND_URL", *backendURL) 74 } 75 76 port := os.Getenv("PORT") 77 if port == "" { 78 port = "8080" 79 } 80 81 // Get the backend dialer warmed up. This starts 82 // RegionInstanceGroupDialer queries and health checks. 83 go sandboxBackendClient() 84 85 log.Printf("Listening on :%v ...", port) 86 log.Fatalf("Error listening on :%v: %v", port, http.ListenAndServe(":"+port, s)) 87 } 88 89 func enableMetrics(s *server) error { 90 gr, err := metrics.GAEResource(context.Background()) 91 if err != nil { 92 s.log.Printf("metrics.GAEResource() = _, %q", err) 93 } 94 ms, err := metrics.NewService(gr, views) 95 if err != nil { 96 s.log.Printf("Failed to initialize metrics: metrics.NewService() = _, %q. (not on GCP?)", err) 97 } 98 if ms != nil && !metadata.OnGCE() { 99 s.mux.Handle("/metrics", ms) 100 } 101 return nil 102 } 103 104 func projectID() string { 105 id, err := metadata.ProjectID() 106 if err != nil && os.Getenv("GAE_INSTANCE") != "" { 107 log.Fatalf("Could not determine the project ID: %v", err) 108 } 109 return id 110 }