diff --git a/instantout/reservation/manager.go b/instantout/reservation/manager.go index 06dedee3..f2833c07 100644 --- a/instantout/reservation/manager.go +++ b/instantout/reservation/manager.go @@ -34,7 +34,9 @@ func NewManager(cfg *Config) *Manager { } // Run runs the reservation manager. -func (m *Manager) Run(ctx context.Context, height int32) error { +func (m *Manager) Run(ctx context.Context, height int32, + initChan chan struct{}) error { + log.Debugf("Starting reservation manager") runCtx, cancel := context.WithCancel(ctx) @@ -55,6 +57,9 @@ func (m *Manager) Run(ctx context.Context, height int32) error { ntfnChan := m.cfg.NotificationManager.SubscribeReservations(runCtx) + // Signal that the manager has been initialized. + close(initChan) + for { select { case height := <-newBlockChan: diff --git a/instantout/reservation/manager_test.go b/instantout/reservation/manager_test.go index 1dbb5a34..226ffb17 100644 --- a/instantout/reservation/manager_test.go +++ b/instantout/reservation/manager_test.go @@ -25,12 +25,16 @@ func TestManager(t *testing.T) { testContext := newManagerTestContext(t) + initChan := make(chan struct{}) // Start the manager. go func() { - err := testContext.manager.Run(ctxb, testContext.mockLnd.Height) + err := testContext.manager.Run(ctxb, testContext.mockLnd.Height, initChan) require.NoError(t, err) }() + // We'll now wait for the manager to be initialized. + <-initChan + // Create a new reservation. reservationFSM, err := testContext.manager.newReservation( ctxb, uint32(testContext.mockLnd.Height), diff --git a/loopd/daemon.go b/loopd/daemon.go index 291c6e54..a7db601b 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -648,6 +648,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { // Start the reservation manager. if d.reservationManager != nil { d.wg.Add(1) + initChan := make(chan struct{}) go func() { defer d.wg.Done() @@ -663,12 +664,25 @@ func (d *Daemon) initialize(withMacaroonService bool) error { defer log.Info("Reservation manager stopped") err = d.reservationManager.Run( - d.mainCtx, int32(getInfo.BlockHeight), + d.mainCtx, int32(getInfo.BlockHeight), initChan, ) if err != nil && !errors.Is(err, context.Canceled) { d.internalErrChan <- err } }() + + // Wait for the reservation server to be ready before starting the + // grpc server. + timeOutCtx, cancel := context.WithTimeout(d.mainCtx, 10*time.Second) + select { + case <-timeOutCtx.Done(): + cancel() + return fmt.Errorf("reservation server not ready: %v", + timeOutCtx.Err()) + + case <-initChan: + cancel() + } } // Start the instant out manager. @@ -701,8 +715,9 @@ func (d *Daemon) initialize(withMacaroonService bool) error { select { case <-timeOutCtx.Done(): cancel() - return fmt.Errorf("reservation server not ready: %v", + return fmt.Errorf("instantout server not ready: %v", timeOutCtx.Err()) + case <-initChan: cancel() }