Merge pull request #96 from notzippy/autorun

Added mutex lock on Refresh, removed check for app existence
This commit is contained in:
notzippy
2017-08-07 20:55:21 -07:00
committed by GitHub
2 changed files with 21 additions and 16 deletions

View File

@@ -29,6 +29,7 @@ import (
"sync/atomic" "sync/atomic"
"github.com/revel/revel" "github.com/revel/revel"
"sync"
) )
var ( var (
@@ -45,6 +46,7 @@ type Harness struct {
port int port int
proxy *httputil.ReverseProxy proxy *httputil.ReverseProxy
watcher *revel.Watcher watcher *revel.Watcher
mutex *sync.Mutex
} }
func renderError(iw http.ResponseWriter, ir *http.Request, err error) { func renderError(iw http.ResponseWriter, ir *http.Request, err error) {
@@ -63,19 +65,17 @@ func (h *Harness) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
// If app did not start when harness was run then trigger the build to capture the error // Flush any change events and rebuild app if necessary.
if h.app == nil { // Render an error page if the rebuild / restart failed.
// Flush any change events and rebuild app if necessary. err := h.watcher.Notify()
// Render an error page if the rebuild / restart failed. if err != nil {
err := h.watcher.Notify() // In a thread safe manner update the flag so that a request for
if err != nil { // /favicon.ico does not trigger a rebuild
// In a thread safe manner update the flag so that a request for atomic.CompareAndSwapInt32(&lastRequestHadError, 0, 1)
// /favicon.ico does not trigger a rebuild renderError(w, r, err)
atomic.CompareAndSwapInt32(&lastRequestHadError, 0, 1) return
renderError(w, r, err)
return
}
} }
// In a thread safe manner update the flag so that a request for // In a thread safe manner update the flag so that a request for
// /favicon.ico is allowed // /favicon.ico is allowed
atomic.CompareAndSwapInt32(&lastRequestHadError, 1, 0) atomic.CompareAndSwapInt32(&lastRequestHadError, 1, 0)
@@ -122,6 +122,7 @@ func NewHarness() *Harness {
port: port, port: port,
serverHost: serverURL.String()[len(scheme+"://"):], serverHost: serverURL.String()[len(scheme+"://"):],
proxy: httputil.NewSingleHostReverseProxy(serverURL), proxy: httputil.NewSingleHostReverseProxy(serverURL),
mutex: &sync.Mutex{},
} }
if revel.HTTPSsl { if revel.HTTPSsl {
@@ -134,6 +135,10 @@ func NewHarness() *Harness {
// Refresh method rebuilds the Revel application and run it on the given port. // Refresh method rebuilds the Revel application and run it on the given port.
func (h *Harness) Refresh() (err *revel.Error) { func (h *Harness) Refresh() (err *revel.Error) {
// Allow only one thread to rebuild the process
h.mutex.Lock()
defer h.mutex.Unlock()
if h.app != nil { if h.app != nil {
h.app.Kill() h.app.Kill()
} }
@@ -162,7 +167,7 @@ func (h *Harness) WatchDir(info os.FileInfo) bool {
} }
// WatchFile method returns true given filename HasSuffix of ".go" // WatchFile method returns true given filename HasSuffix of ".go"
// otheriwse false // otheriwse false - implements revel.DiscerningListener
func (h *Harness) WatchFile(filename string) bool { func (h *Harness) WatchFile(filename string) bool {
return strings.HasSuffix(filename, ".go") return strings.HasSuffix(filename, ".go")
} }

View File

@@ -51,7 +51,7 @@ func parseRunArgs(args []string) *RunArgs {
} }
switch len(args) { switch len(args) {
case 3: case 3:
// Possibile combinations // Possible combinations
// revel run [import-path] [run-mode] [port] // revel run [import-path] [run-mode] [port]
port, err := strconv.Atoi(args[2]) port, err := strconv.Atoi(args[2])
if err != nil { if err != nil {
@@ -61,7 +61,7 @@ func parseRunArgs(args []string) *RunArgs {
inputArgs.Mode = args[1] inputArgs.Mode = args[1]
inputArgs.Port = port inputArgs.Port = port
case 2: case 2:
// Possibile combinations // Possible combinations
// 1. revel run [import-path] [run-mode] // 1. revel run [import-path] [run-mode]
// 2. revel run [import-path] [port] // 2. revel run [import-path] [port]
// 3. revel run [run-mode] [port] // 3. revel run [run-mode] [port]
@@ -85,7 +85,7 @@ func parseRunArgs(args []string) *RunArgs {
inputArgs.Port = port inputArgs.Port = port
} }
case 1: case 1:
// Possibile combinations // Possible combinations
// 1. revel run [import-path] // 1. revel run [import-path]
// 2. revel run [port] // 2. revel run [port]
// 3. revel run [run-mode] // 3. revel run [run-mode]