Skip to content

Commit

Permalink
fix: Wait no actually waiting
Browse files Browse the repository at this point in the history
Somewhere along the way, lost the wait functionality. Refactored a few
things.

1. Got rid of status on the proxy. Simplify, just see if the error
string is set instead

2. Had to fix a blocking condition - when waiting, but the command you
are waiting on errors. Tychus would get stuck waiting for a read on the
errors channel, because it was already ready on the proxy.request
channel.
  • Loading branch information
PatKoperwas committed Mar 6, 2018
1 parent 8abd8f7 commit 4426e7c
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 39 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/spf13/cobra"
)

var version = "0.6.2"
var version = "0.6.3"

var appPort int
var debug bool
Expand Down
28 changes: 15 additions & 13 deletions tychus/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
// but before it is ready to accept requests.
package tychus

import "time"

type Orchestrator struct {
config *Configuration
watcher *watcher
Expand All @@ -31,37 +33,37 @@ func (o *Orchestrator) Start() error {
stop := make(chan error, 1)

go func() {
err := o.proxy.start()
if err != nil {
if err := o.proxy.start(); err != nil {
stop <- err
}
}()

err := o.runner.run()
if err != nil {
o.proxy.error(err)
if err := o.runner.run(); err != nil {
o.proxy.setError(err)
}

for {
select {
case <-o.proxy.requests:
o.config.Logger.Debug("Request started")

modified := o.watcher.scan()
if modified || o.proxy.mode == mode_errored {
o.config.Logger.Debug("Rerunnning")
if modified {
o.config.Logger.Debug("Runner: FS modified, rerunning")

if err := o.runner.run(); err != nil {
o.proxy.error(err)
o.proxy.setError(err)
o.proxy.unpause <- true
continue
}

o.proxy.clearError()
}

o.proxy.serve()
o.watcher.lastRun = time.Now()
o.proxy.unpause <- true

case err := <-o.runner.errors:
o.config.Logger.Debug("Runner errored")
o.proxy.error(err)
o.config.Logger.Debug("Runner: Error")
o.proxy.setError(err)

case err := <-stop:
o.Stop()
Expand Down
29 changes: 11 additions & 18 deletions tychus/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,12 @@ import (
"time"
)

type mode uint32

const (
mode_errored mode = 1 << iota
mode_serving
)

type proxy struct {
config *Configuration
errorStr string
mode mode
requests chan bool
revproxy *httputil.ReverseProxy
unpause chan bool
}

// Returns a newly configured proxy
Expand All @@ -38,9 +31,9 @@ func newProxy(c *Configuration) *proxy {

p := &proxy{
config: c,
revproxy: revproxy,
mode: mode_serving,
requests: make(chan bool),
revproxy: revproxy,
unpause: make(chan bool),
}

return p
Expand Down Expand Up @@ -69,6 +62,8 @@ func (p *proxy) start() error {
func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
p.requests <- true

<-p.unpause

if ok := p.forward(w, r); ok {
return
}
Expand Down Expand Up @@ -99,7 +94,7 @@ func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}

func (p *proxy) forward(w http.ResponseWriter, r *http.Request) bool {
if p.mode == mode_errored {
if len(p.errorStr) > 0 {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(p.errorStr))
return true
Expand All @@ -113,17 +108,15 @@ func (p *proxy) forward(w http.ResponseWriter, r *http.Request) bool {
return writer.status != http.StatusBadGateway
}

func (p *proxy) serve() {
p.config.Logger.Debug("Proxy: Serving")
p.mode = mode_serving
}

func (p *proxy) error(err error) {
func (p *proxy) setError(err error) {
p.config.Logger.Debug("Proxy: Error Mode")
p.mode = mode_errored
p.errorStr = err.Error()
}

func (p *proxy) clearError() {
p.errorStr = ""
}

// Wrapper around http.ResponseWriter. Since the proxy works rather naively -
// it just retries requests over and over until it gets a response from the app
// server - we can't use the ResponseWriter that is passed to the handler
Expand Down
14 changes: 11 additions & 3 deletions tychus/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (r *runner) run() error {
}

if r.config.Wait {
r.wait()
return r.wait()
} else {
go r.wait()
}
Expand Down Expand Up @@ -68,17 +68,25 @@ func (r *runner) execute() error {
// Wait for the command to finish. If the process exits with an error, only log
// it if it exit status is postive, as status code -1 is returned when the
// process was killed by runner#kill.
func (r *runner) wait() {
func (r *runner) wait() error {
err := r.cmd.Wait()

if err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
ws := exiterr.Sys().(syscall.WaitStatus)
if ws.ExitStatus() > 0 {
r.errors <- errors.New(r.stderr.String())
err = errors.New(r.stderr.String())

if r.config.Wait {
return err
} else {
r.errors <- err
}
}
}
}

return nil
}

// Kill the existing process & process group
Expand Down
7 changes: 3 additions & 4 deletions tychus/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func newWatcher(c *Configuration) *watcher {
}

func (w *watcher) scan() bool {
w.config.Logger.Debug("Scan: Start")
w.config.Logger.Debug("Watcher: Start")
start := time.Now()

modified := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
Expand All @@ -30,15 +30,14 @@ func (w *watcher) scan() bool {
}

if info.ModTime().After(w.lastRun) {
w.config.Logger.Debugf("Watcher: Found modified file: %v", path)
return errors.New(path)
}

return nil
})

w.config.Logger.Debugf("Scan: took: %v", time.Since(start))

w.lastRun = time.Now()
w.config.Logger.Debugf("Watcher: Scan finished: %v", time.Since(start))

return modified != nil
}
Expand Down

0 comments on commit 4426e7c

Please sign in to comment.