@@ -12,6 +12,7 @@ import (
1212 "os"
1313 "os/exec"
1414 "time"
15+ "sync"
1516
1617 "github.com/revel/cmd/model"
1718 "github.com/revel/cmd/utils"
@@ -21,15 +22,16 @@ import (
2122// App contains the configuration for running a Revel app. (Not for the app itself)
2223// Its only purpose is constructing the command to execute.
2324type App struct {
24- BinaryPath string // Path to the app executable
25- Port int // Port to pass as a command line argument.
26- cmd AppCmd // The last cmd returned.
27- Paths * model.RevelContainer
25+ BinaryPath string // Path to the app executable
26+ Port int // Port to pass as a command line argument.
27+ cmd AppCmd // The last cmd returned.
28+ PackagePathMap map [string ]string // Package to directory path map
29+ Paths * model.RevelContainer
2830}
2931
3032// NewApp returns app instance with binary path in it
31- func NewApp (binPath string , paths * model.RevelContainer ) * App {
32- return & App {BinaryPath : binPath , Paths : paths , Port : paths .HTTPPort }
33+ func NewApp (binPath string , paths * model.RevelContainer , packagePathMap map [ string ] string ) * App {
34+ return & App {BinaryPath : binPath , Paths : paths , Port : paths .HTTPPort , PackagePathMap : packagePathMap }
3335}
3436
3537// Cmd returns a command to run the app server using the current configuration.
@@ -63,18 +65,18 @@ func NewAppCmd(binPath string, port int, runMode string, paths *model.RevelConta
6365func (cmd AppCmd ) Start (c * model.CommandConfig ) error {
6466 listeningWriter := & startupListeningWriter {os .Stdout , make (chan bool ), c , & bytes.Buffer {}}
6567 cmd .Stdout = listeningWriter
68+ utils .CmdInit (cmd .Cmd , ! c .Vendored , c .AppPath )
6669 utils .Logger .Info ("Exec app:" , "path" , cmd .Path , "args" , cmd .Args , "dir" , cmd .Dir , "env" , cmd .Env )
67- utils .CmdInit (cmd .Cmd , c .AppPath )
6870 if err := cmd .Cmd .Start (); err != nil {
6971 utils .Logger .Fatal ("Error running:" , "error" , err )
7072 }
7173
7274 select {
7375 case exitState := <- cmd .waitChan ():
7476 fmt .Println ("Startup failure view previous messages, \n Proxy is listening :" , c .Run .Port )
75- err := utils .NewError ("" ,"Revel Run Error" , "starting your application there was an exception. See terminal output, " + exitState ,"" )
76- // TODO pretiffy command line output
77- // err.MetaError = listeningWriter.getLastOutput()
77+ err := utils .NewError ("" , "Revel Run Error" , "starting your application there was an exception. See terminal output, " + exitState , "" )
78+ // TODO pretiffy command line output
79+ // err.MetaError = listeningWriter.getLastOutput()
7880 return err
7981
8082 case <- time .After (60 * time .Second ):
@@ -106,10 +108,30 @@ func (cmd AppCmd) Kill() {
106108 // server before this can, this check will ensure the process is still running
107109 if _ , err := os .FindProcess (int (cmd .Process .Pid ));err != nil {
108110 // Server has already exited
109- utils .Logger .Info ("Killing revel server pid" , "pid" , cmd .Process .Pid )
111+ utils .Logger .Info ("Server not running revel server pid" , "pid" , cmd .Process .Pid )
110112 return
111113 }
112114
115+ // Wait for the shutdown channel
116+ waitMutex := & sync.WaitGroup {}
117+ waitMutex .Add (1 )
118+ ch := make (chan bool , 1 )
119+ go func () {
120+ waitMutex .Done ()
121+ s , err := cmd .Process .Wait ()
122+ defer func () {
123+ ch <- true
124+ }()
125+ if err != nil {
126+ utils .Logger .Info ("Wait failed for process " , "error" , err )
127+ }
128+ if s != nil {
129+ utils .Logger .Info ("Revel App exited" , "state" , s .String ())
130+ }
131+ }()
132+ // Wait for the channel to begin waiting
133+ waitMutex .Wait ()
134+
113135 // Send an interrupt signal to allow for a graceful shutdown
114136 utils .Logger .Info ("Killing revel server pid" , "pid" , cmd .Process .Pid )
115137 var err error
@@ -128,28 +150,14 @@ func (cmd AppCmd) Kill() {
128150 return
129151 }
130152
131- // Wait for the shutdown
132- ch := make (chan bool , 1 )
133- go func () {
134- s , err := cmd .Process .Wait ()
135- defer func () {
136- ch <- true
137- }()
138- if err != nil {
139- utils .Logger .Info ("Wait failed for process " , "error" , err )
140- }
141- if s != nil {
142- utils .Logger .Info ("Revel App exited" , "state" , s .String ())
143- }
144- }()
145153
146154 // Use a timer to ensure that the process exits
147155 utils .Logger .Info ("Waiting to exit" )
148156 select {
149157 case <- ch :
150158 return
151159 case <- time .After (60 * time .Second ):
152- // Kill the process
160+ // Kill the process
153161 utils .Logger .Error (
154162 "Revel app failed to exit in 60 seconds - killing." ,
155163 "processid" , cmd .Process .Pid ,
@@ -198,7 +206,7 @@ func (w *startupListeningWriter) Write(p []byte) (int, error) {
198206 w .notifyReady = nil
199207 }
200208 }
201- if w .notifyReady != nil {
209+ if w .notifyReady != nil {
202210 w .buffer .Write (p )
203211 }
204212 return w .dest .Write (p )
0 commit comments