service: update windows to return error from Start and Stop methods.

This commit is contained in:
Daniel Theophanes
2015-01-18 14:30:15 -08:00
parent 0de2108b82
commit 816e28277e
+31 -5
View File
@@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
"sync"
"time" "time"
"bitbucket.org/kardianos/osext" "bitbucket.org/kardianos/osext"
@@ -21,6 +22,9 @@ const version = "Windows Service"
type windowsService struct { type windowsService struct {
i Interface i Interface
*Config *Config
errSync sync.Mutex
stopStartErr error
} }
// WindowsLogger allows using windows specific logging methods. // WindowsLogger allows using windows specific logging methods.
@@ -112,13 +116,23 @@ func (ws *windowsService) String() string {
return ws.Name return ws.Name
} }
func (ws *windowsService) setError(err error) {
ws.errSync.Lock()
defer ws.errSync.Unlock()
ws.stopStartErr = err
}
func (ws *windowsService) getError() error {
ws.errSync.Lock()
defer ws.errSync.Unlock()
return ws.stopStartErr
}
func (ws *windowsService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) { func (ws *windowsService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending} changes <- svc.Status{State: svc.StartPending}
if err := ws.i.Start(ws); err != nil { if err := ws.i.Start(ws); err != nil {
// TODO: log error. ws.setError(err)
// ws.Error(err.Error())
return true, 1 return true, 1
} }
@@ -132,8 +146,7 @@ loop:
case svc.Stop, svc.Shutdown: case svc.Stop, svc.Shutdown:
changes <- svc.Status{State: svc.StopPending} changes <- svc.Status{State: svc.StopPending}
if err := ws.i.Stop(ws); err != nil { if err := ws.i.Stop(ws); err != nil {
// TODO: Log error. ws.setError(err)
// ws.Error(err.Error())
return true, 2 return true, 2
} }
break loop break loop
@@ -202,8 +215,21 @@ func (ws *windowsService) Uninstall() error {
} }
func (ws *windowsService) Run() error { func (ws *windowsService) Run() error {
ws.setError(nil)
if !interactive { if !interactive {
return svc.Run(ws.Name, ws) // Return error messages from start and stop routines
// that get executed in the Execute method.
// Guarded with a mutex as it may run a different thread
// (callback from windows).
runErr := svc.Run(ws.Name, ws)
startStopErr := ws.getError()
if startStopErr != nil {
return startStopErr
}
if runErr != nil {
return runErr
}
return nil
} }
err := ws.i.Start(ws) err := ws.i.Start(ws)
if err != nil { if err != nil {