1 // Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
2 // Revel Framework source code and usage is governed by a MIT style
3 // license that can be found in the LICENSE file.
9 "github.com/revel/revel/session"
13 "github.com/revel/revel/utils"
16 // Revel's variables server, router, etc
19 MainTemplateLoader *TemplateLoader
21 serverEngineMap = map[string]func() ServerEngine{}
22 CurrentEngine ServerEngine
23 ServerEngineInit *EngineInit
24 serverLogger = RevelLog.New("section", "server")
27 func RegisterServerEngine(name string, loader func() ServerEngine) {
28 serverLogger.Debug("RegisterServerEngine: Registered engine ", "name", name)
29 serverEngineMap[name] = loader
32 // InitServer initializes the server and returns the handler
33 // It can be used as an alternative entry-point if one needs the http handler
34 // to be exposed. E.g. to run on multiple addresses and ports or to set custom
37 CurrentEngine.Init(ServerEngineInit)
42 MainTemplateLoader = NewTemplateLoader(TemplatePaths)
43 if err := MainTemplateLoader.Refresh(); err != nil {
44 serverLogger.Debug("InitServer: Main template loader failed to refresh", "error", err)
47 // The "watch" config variable can turn on and off all watching.
48 // (As a convenient way to control it all together.)
49 if Config.BoolDefault("watch", true) {
50 MainWatcher = NewWatcher()
51 Filters = append([]Filter{WatchFilter}, Filters...)
54 // If desired (or by default), create a watcher for templates and routes.
55 // The watcher calls Refresh() on things on the first request.
56 if MainWatcher != nil && Config.BoolDefault("watch.templates", true) {
57 MainWatcher.Listen(MainTemplateLoader, MainTemplateLoader.paths...)
63 // This is called from the generated main file.
64 // If port is non-zero, use that. Else, read the port from app.conf.
67 if r := recover(); r != nil {
68 RevelLog.Crit("Recovered error in startup", "error", r)
69 RaiseEvent(REVEL_FAILURE, r)
70 panic("Fatal error in startup")
74 // Initialize the session logger, must be initiated from this app to avoid
75 // circular references
76 session.InitSession(RevelLog)
78 // Create the CurrentEngine instance from the application config
79 InitServerEngine(port, Config.StringDefault("server.engine", GO_NATIVE_SERVER_ENGINE))
80 RaiseEvent(ENGINE_BEFORE_INITIALIZED, nil)
82 RaiseEvent(ENGINE_STARTED, nil)
83 // This is needed for the harness to recognize that the server is started, it looks for the word
84 // "Listening" in the stdout stream
86 fmt.Fprintf(os.Stdout, "Revel engine is listening on.. %s\n", ServerEngineInit.Address)
87 // Start never returns,
89 fmt.Fprintf(os.Stdout, "Revel engine is NOT listening on.. %s\n", ServerEngineInit.Address)
90 RaiseEvent(ENGINE_SHUTDOWN, nil)
92 println("\nRevel exited normally\n")
95 // Build an engine initialization object and start the engine
96 func InitServerEngine(port int, serverEngine string) {
106 var localAddress string
108 // If the port is zero, treat the address as a fully qualified local address.
109 // This address must be prefixed with the network type followed by a colon,
110 // e.g. unix:/tmp/app.socket or tcp6:::1 (equivalent to tcp6:0:0:0:0:0:0:0:1)
112 parts := strings.SplitN(address, ":", 2)
114 localAddress = parts[1]
116 localAddress = address + ":" + strconv.Itoa(port)
119 if engineLoader, ok := serverEngineMap[serverEngine]; !ok {
120 panic("Server Engine " + serverEngine + " Not found")
122 CurrentEngine = engineLoader()
123 serverLogger.Debug("InitServerEngine: Found server engine and invoking", "name", CurrentEngine.Name())
124 ServerEngineInit = &EngineInit{
125 Address: localAddress,
128 Callback: handleInternal,
131 AddInitEventHandler(CurrentEngine.Event)
134 // Initialize the controller stack for the application
135 func initControllerStack() {
136 RevelConfig.Controller.Reuse = Config.BoolDefault("revel.controller.reuse",true)
138 if RevelConfig.Controller.Reuse {
139 RevelConfig.Controller.Stack = utils.NewStackLock(
140 Config.IntDefault("revel.controller.stack", 10),
141 Config.IntDefault("revel.controller.maxstack", 200), func() interface{} {
142 return NewControllerEmpty()
144 RevelConfig.Controller.CachedStackSize = Config.IntDefault("revel.cache.controller.stack", 10)
145 RevelConfig.Controller.CachedStackMaxSize = Config.IntDefault("revel.cache.controller.maxstack", 100)
146 RevelConfig.Controller.CachedMap = map[string]*utils.SimpleLockStack{}
150 // Called to stop the server
151 func StopServer(value interface{}) EventResponse {
152 return RaiseEvent(ENGINE_SHUTDOWN_REQUEST,value)