// Starts and runs the server given its configuration. (This function never returns.) func RunServer(config *ServerConfig) { PrettyPrint = config.Pretty if os.Getenv("GOMAXPROCS") == "" && runtime.GOMAXPROCS(0) == 1 { cpus := runtime.NumCPU() if cpus > 1 { runtime.GOMAXPROCS(cpus) base.Log("Configured Go to use all %d CPUs; setenv GOMAXPROCS to override this", cpus) } } sc := NewServerContext(config) for _, dbConfig := range config.Databases { if err := sc.AddDatabaseFromConfig(dbConfig); err != nil { base.LogFatal("Error opening database: %v", err) } } base.Log("Starting admin server on %s", *config.AdminInterface) go func() { if err := http.ListenAndServe(*config.AdminInterface, CreateAdminHandler(sc)); err != nil { base.LogFatal("HTTP server failed: %v", err) } }() base.Log("Starting server on %s ...", *config.Interface) if err := http.ListenAndServe(*config.Interface, CreatePublicHandler(sc)); err != nil { base.LogFatal("HTTP server failed: %v", err) } }
// Starts and runs the server given its configuration. (This function never returns.) func RunServer(config *ServerConfig) { PrettyPrint = config.Pretty base.Log("==== %s ====", LongVersionString) if os.Getenv("GOMAXPROCS") == "" && runtime.GOMAXPROCS(0) == 1 { cpus := runtime.NumCPU() if cpus > 1 { runtime.GOMAXPROCS(cpus) base.Log("Configured Go to use all %d CPUs; setenv GOMAXPROCS to override this", cpus) } } setMaxFileDescriptors(config.MaxFileDescriptors) sc := NewServerContext(config) for _, dbConfig := range config.Databases { if _, err := sc.AddDatabaseFromConfig(dbConfig); err != nil { base.LogFatal("Error opening database: %v", err) } } if config.ProfileInterface != nil { //runtime.MemProfileRate = 10 * 1024 base.Log("Starting profile server on %s", *config.ProfileInterface) go func() { http.ListenAndServe(*config.ProfileInterface, nil) }() } base.Log("Starting admin server on %s", *config.AdminInterface) go config.serve(*config.AdminInterface, CreateAdminHandler(sc)) base.Log("Starting server on %s ...", *config.Interface) config.serve(*config.Interface, CreatePublicHandler(sc)) }
// Starts and runs the server given its configuration. (This function never returns.) func RunServer(config *ServerConfig) { PrettyPrint = config.Pretty sc := newServerContext(config) for _, dbConfig := range config.Databases { if err := sc.addDatabaseFromConfig(dbConfig); err != nil { base.LogFatal("Error opening database: %v", err) } } http.Handle("/", createHandler(sc)) base.Log("Starting auth server on %s", *config.AdminInterface) StartAuthListener(*config.AdminInterface, sc) base.Log("Starting server on %s ...", *config.Interface) if err := http.ListenAndServe(*config.Interface, nil); err != nil { base.LogFatal("Server failed: ", err.Error()) } }
func (config *ServerConfig) serve(addr string, handler http.Handler) { maxConns := DefaultMaxIncomingConnections if config.MaxIncomingConnections != nil { maxConns = *config.MaxIncomingConnections } err := base.ListenAndServeHTTP(addr, maxConns, config.SSLCert, config.SSLKey, handler) if err != nil { base.LogFatal("Failed to start HTTP server on %s: %v", addr, err) } }
func setMaxFileDescriptors(maxP *uint64) { maxFDs := DefaultMaxFileDescriptors if maxP != nil { maxFDs = *maxP } var limits syscall.Rlimit if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limits); err != nil { base.LogFatal("Getrlimit failed: %v", err) } if maxFDs > limits.Max { maxFDs = limits.Max } if limits.Cur != maxFDs { limits.Cur = maxFDs limits.Max = maxFDs err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limits) if err != nil { base.LogFatal("Error raising MaxFileDescriptors to %d: %v", maxFDs, err) } base.Log("Configured MaxFileDescriptors (RLIMIT_NOFILE) to %d", maxFDs) } }
// Reads the command line flags and the optional config file. func ParseCommandLine() *ServerConfig { siteURL := flag.String("personaOrigin", "", "Base URL that clients use to connect to the server") addr := flag.String("interface", DefaultInterface, "Address to bind to") authAddr := flag.String("adminInterface", DefaultAdminInterface, "Address to bind admin interface to") couchbaseURL := flag.String("url", DefaultServer, "Address of Couchbase server") poolName := flag.String("pool", DefaultPool, "Name of pool") bucketName := flag.String("bucket", "sync_gateway", "Name of bucket") dbName := flag.String("dbname", "", "Name of CouchDB database (defaults to name of bucket)") pretty := flag.Bool("pretty", false, "Pretty-print JSON responses") verbose := flag.Bool("verbose", false, "Log more info about requests") logKeys := flag.String("log", "", "Log keywords, comma separated") flag.Parse() var config *ServerConfig if flag.NArg() > 0 { // Read the configuration file(s), if any: for i := 0; i < flag.NArg(); i++ { filename := flag.Arg(i) c, err := ReadConfig(filename) if err != nil { base.LogFatal("Error reading config file %s: %v", filename, err) } if config == nil { config = c } else { if err := config.MergeWith(c); err != nil { base.LogFatal("Error reading config file %s: %v", filename, err) } } } // Override the config file with global settings from command line flags: if *addr != DefaultInterface { config.Interface = addr } if *authAddr != DefaultAdminInterface { config.AdminInterface = authAddr } if *pretty { config.Pretty = *pretty } if config.Log != nil { base.ParseLogFlags(config.Log) } if len(config.Databases) == 0 { base.LogFatal("No databases!") } if config.Interface == nil { config.Interface = &DefaultInterface } if config.AdminInterface == nil { config.AdminInterface = &DefaultAdminInterface } } else { // If no config file is given, create a default config, filled in from command line flags: if *dbName == "" { *dbName = *bucketName } config = &ServerConfig{ Interface: addr, AdminInterface: authAddr, Pretty: *pretty, Databases: map[string]*DbConfig{ *dbName: { Server: couchbaseURL, Bucket: bucketName, Pool: poolName, }, }, } } if *siteURL != "" { config.Persona = &PersonaConfig{Origin: *siteURL} } base.LogKeys["HTTP"] = true base.LogKeys["HTTP+"] = *verbose base.ParseLogFlag(*logKeys) return config }