@@ -10,7 +10,6 @@ import (
1010 "github.com/eapache/go-resiliency/retrier"
1111 "github.com/pkg/errors"
1212 "go.uber.org/zap"
13- "golang.org/x/sync/errgroup"
1413 "gopkg.in/src-d/go-git.v4/plumbing/transport"
1514 "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
1615 "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
@@ -110,39 +109,43 @@ func Initialise(c Config) (app *App, err error) {
110109
111110// Start launches the app and blocks until fatal error
112111func (app * App ) Start (ctx context.Context ) error {
113- g , ctx := errgroup .WithContext (ctx )
114-
115- zap .L ().Debug ("starting service daemon" )
116-
117- // TODO: Replace this errgroup with a more resilient solution.
118- // Not all of these tasks fail in the same way. Some don't fail at all.
119- // This needs to be rewritten to be more considerate of different failure
120- // states and potentially retry in some circumstances. Pico should be the
121- // kind of service that barely goes down, only when absolutely necessary.
112+ errs := make (chan error )
122113
123114 ce := executor .NewCommandExecutor (app .secrets , app .config .PassEnvironment , app .config .VaultConfig , "GLOBAL_" )
124- g . Go ( func () error {
115+ go func () {
125116 ce .Subscribe (app .bus )
126- return nil
127- })
117+ }()
128118
129- // TODO: gw can fail when setting up the gitwatch instance, it should retry.
130119 gw := app .watcher .(* watcher.GitWatcher )
131- g .Go (gw .Start )
120+ go func () {
121+ errs <- errors .Wrap (gw .Start (), "git watcher terminated fatally" )
122+ }()
132123
133- // TODO: reconfigurer can also fail when setting up gitwatch.
134- g .Go (func () error {
135- return app .reconfigurer .Configure (app .watcher )
136- })
124+ go func () {
125+ errs <- errors .Wrap (app .reconfigurer .Configure (app .watcher ), "git watcher terminated fatally" )
126+ }()
137127
138128 if s , ok := app .secrets .(* vault.VaultSecrets ); ok {
139- g .Go (func () error {
140- return retrier .New (retrier .ConstantBackoff (3 , 100 * time .Millisecond ), nil ).
141- RunCtx (ctx , s .Renew )
142- })
129+ go func () {
130+ errs <- errors .Wrap (retrier .New (retrier .ConstantBackoff (3 , 100 * time .Millisecond ), nil ).RunCtx (ctx , s .Renew ), "git watcher terminated fatally" )
131+ }()
143132 }
144133
145- return g .Wait ()
134+ handle := func () error {
135+ select {
136+ case err := <- errs :
137+ return err
138+ case <- ctx .Done ():
139+ return context .Canceled
140+ }
141+ }
142+
143+ zap .L ().Debug ("starting service main loop" )
144+ for {
145+ if err := handle (); err != nil {
146+ return err
147+ }
148+ }
146149}
147150
148151func getAuthMethod (c Config , secretConfig map [string ]string ) (transport.AuthMethod , error ) {
0 commit comments