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  }